From dbecdc5618add962f8b3ee65a551ed8808e83fab Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Thu, 9 Nov 2017 17:10:30 -0800 Subject: [PATCH] feat: prep for modern challenges (#15781) * feat(seed): Add modern challenge * chore(react): Use prop-types package * feat: Initial refactor to redux-first-router BREAKING CHANGE: Everything is different! * feat: First rendering * feat(routes): Challenges view render but failing * fix(Challenges): Remove contain HOC * fix(RFR): Add params selector * fix(RFR): :en should be :lang * fix: Update berks utils for redux * fix(Map): Challenge link to arg * fix(Map): Add trailing slash to map page * fix(RFR): Use FCC Link Use fcc Link to get around issue of lang being undefined * fix(Router): Link to is required * fix(app): Rely on RFR state for app lang * chore(RFR): Remove unused RFR Link * fix(RFR): Hydrate initial challenge using RFR and RO * fix: Casing issue * fix(RFR): Undefined links * fix(RFR): Use onRoute convention for route types * feat(server/react): Add helpful redux logging/throwing * fix(server/react): Strip out nonjson from state This prevents thunks in routesMap from breaking serialization * fix(RFR/Link): Should accept any renderable * fix(RFR): Get redirects working * fix(RFR): Redirects and not found's * fix(Map): Move challenge onClick handler * fix(Map): Allow Router.link to handle clicks after onClick * fix(routes): Remove react-router-redux * feat(Router): Add lang to all route actions by default * fix(entities): Only fetch challenge if not already loaded * fix(Files): Move files to own feature * chore(Challenges): Remove vestigial hints logic * fix(RFR): Update challenges on route challenges * fix(code-storage): Should use events instead of commands * fix(Map): ClickOnMap should not hold on to event * chore(lint): Use eslint-config-freecodecamp Closes #15938 * feat(Panes): Update panes on route instead of render * fix(Panes): Store panesmap and update on fetchchallenges * fix(Panes): Normalize panesmaps * fix(Panes): Remove filter from createpanemap * fix(Panes): Middleware on location meta object * feat(Panes): Filter preview on nonhtml challenges * build(babel): Add lodash babel plugin * chore(lint): Lint js files * fix(server/user-stats): Remove use of lodash chain this interferes with babel-plugin-lodash * feat(dev): Add remote redux devtools for ssr * fix(Panes): Dispatch mount action this is needed to trigger window/divider epics * fix(Panes): Getpane to use new panesmap format * fix(Panes): Always update panes after state this lets the panes logic be affected by changes in state --- .babelrc | 5 +- .eslintrc | 206 +- client/epics/analytics-epic.js | 2 +- client/epics/code-storage-epic.js | 22 +- client/epics/execute-challenge-epic.js | 8 +- client/epics/frame-epic.js | 2 +- client/epics/hard-go-to-epic.js | 2 +- client/epics/mouse-trap-epic.js | 2 +- client/index.js | 33 +- common/app/App.jsx | 41 +- common/app/Child-Container.jsx | 3 +- common/app/Map/Block.jsx | 3 +- common/app/Map/Challenge.jsx | 23 +- common/app/Map/Map.jsx | 3 +- common/app/Map/Super-Block.jsx | 3 +- common/app/Map/redux/index.js | 90 +- common/app/Map/redux/select-challenge-epic.js | 10 - common/app/Nav/Bin-Button.jsx | 3 +- common/app/Nav/Nav.jsx | 54 +- common/app/Nav/Sign-Up.jsx | 9 +- common/app/Nav/redux/index.js | 20 +- .../Nav/redux/load-current-challenge-epic.js | 7 +- common/app/NotFound/Not-Found.jsx | 22 +- common/app/Panes/Divider.jsx | 3 +- common/app/Panes/Pane.jsx | 3 +- common/app/Panes/Panes-Container.jsx | 34 +- common/app/Panes/Panes.jsx | 5 +- common/app/Panes/redux/index.js | 335 +- common/app/Router/Link.jsx | 80 + common/app/Router/handle-press.js | 50 + common/app/Router/index.js | 1 + common/app/Router/redux/add-lang-enhancer.js | 28 + common/app/Router/redux/index.js | 5 + common/app/Router/to-url.js | 45 + common/app/Toasts/Toasts.jsx | 9 +- common/app/Toasts/redux/index.js | 22 +- common/app/app.less | 2 +- common/app/create-app.jsx | 82 +- common/app/create-reducer.js | 42 - common/app/create-routes.js | 9 - common/app/entities/index.js | 103 +- common/app/epics.js | 4 +- common/app/files/index.js | 97 + common/app/index.js | 4 +- common/app/provide-store.js | 8 +- common/app/reducer.js | 26 + common/app/redux/fetch-challenges-epic.js | 22 +- common/app/redux/fetch-user-epic.js | 2 +- common/app/redux/index.js | 118 +- common/app/redux/update-my-challenge-epic.js | 5 +- common/app/redux/utils.js | 2 +- common/app/routes-map.js | 19 + .../{challenges => Challenges}/Bug-Modal.jsx | 3 +- .../Challenge-Description.jsx | 3 +- .../Challenge-Title.jsx | 3 +- .../Code-Mirror-Skeleton.jsx | 3 +- .../Completion-Modal.jsx | 3 +- .../{challenges => Challenges}/Output.jsx | 3 +- common/app/routes/Challenges/Show.jsx | 113 + .../Solution-Input.jsx | 3 +- .../{challenges => Challenges}/Test-Suite.jsx | 3 +- .../challenges.less | 0 common/app/routes/Challenges/index.js | 33 + .../routes/{challenges => Challenges}/ns.json | 0 .../redux/bug-epic.js | 5 +- .../redux/challenge-epic.js | 56 +- .../redux/completion-epic.js | 59 +- .../redux/editor-epic.js | 4 +- .../{challenges => Challenges}/redux/index.js | 196 +- .../{challenges => Challenges}/utils.js | 32 - .../{challenges => Challenges}/utils.test.js | 0 .../views/backend/Back-End.jsx | 3 +- .../views/backend/Show.jsx | 12 +- .../views/backend/index.js | 0 .../views/classic/Editor.jsx | 6 +- .../views/classic/Preview.jsx | 0 .../views/classic/Show.jsx | 21 +- .../views/classic/Side-Panel.jsx | 9 +- .../views/classic/Tool-Panel.jsx | 5 +- .../views/classic/classic.less | 0 .../views/classic/index.js | 0 .../views/classic/ns.json | 0 .../views/index.less | 0 .../views/project/Forms.jsx | 3 +- .../views/project/Project.jsx | 3 +- .../views/project/Show.jsx | 13 +- .../views/project/Side-Panel.jsx | 3 +- .../views/project/Tool-Panel.jsx | 3 +- .../views/project/index.js | 0 .../views/project/ns.json | 0 .../views/project/redux/index.js | 20 +- .../views/project/redux/project-normalizer.js | 0 .../views/quiz/Choice.jsx | 3 +- .../views/quiz/Quiz.jsx | 3 +- .../views/quiz/Show.jsx | 13 +- .../views/quiz/index.js | 0 .../views/quiz/ns.json | 0 .../views/quiz/quiz.less | 0 .../views/quiz/redux/index.js | 20 +- .../views/step/Show.jsx | 13 +- .../views/step/Step.jsx | 3 +- .../views/step/index.js | 0 .../views/step/ns.json | 0 .../views/step/redux/index.js | 21 +- .../views/step/redux/step-challenge-epic.js | 0 .../step/redux/step-challenge-epic.test.js | 6 +- .../views/step/step.less | 0 common/app/routes/Map/index.js | 10 + .../{settings => Settings}/Email-Setting.jsx | 9 +- .../{settings => Settings}/Job-Settings.jsx | 3 +- .../Language-Settings.jsx | 3 +- .../Locked-Settings.jsx | 3 +- .../Settings-Skeleton.jsx | 0 .../{settings => Settings}/Settings.jsx | 4 +- .../Social-Settings.jsx | 3 +- common/app/routes/Settings/index.js | 8 + .../app/routes/{settings => Settings}/ns.json | 0 common/app/routes/Settings/redux/index.js | 42 + .../redux/update-user-epic.js | 5 +- .../routes/update-email/Update-Email.jsx | 15 +- .../routes/update-email/index.js | 0 .../{settings => Settings}/settings.less | 0 common/app/routes/challenges/Show.jsx | 140 - common/app/routes/challenges/index.js | 32 - common/app/routes/index.js | 53 +- common/app/routes/index.less | 4 +- common/app/routes/map/index.js | 6 - common/app/routes/redux.js | 37 +- common/app/routes/settings/index.js | 10 - common/app/routes/settings/redux/index.js | 21 - common/app/utils/No-Props-Passthrough.jsx | 2 +- common/app/utils/classic-file.js | 33 + common/app/utils/redux-first-router.js | 26 + common/utils/wait-for-epics.js | 15 + package-lock.json | 5056 +++++++++++------ package.json | 17 +- .../03-front-end-libraries/react.json | 44 +- server/boot/certificate.js | 3 +- server/boot/react.js | 99 +- server/utils/react.js | 15 + server/utils/user-stats.js | 9 +- 141 files changed, 4984 insertions(+), 3186 deletions(-) delete mode 100644 common/app/Map/redux/select-challenge-epic.js create mode 100644 common/app/Router/Link.jsx create mode 100644 common/app/Router/handle-press.js create mode 100644 common/app/Router/index.js create mode 100644 common/app/Router/redux/add-lang-enhancer.js create mode 100644 common/app/Router/redux/index.js create mode 100644 common/app/Router/to-url.js delete mode 100644 common/app/create-reducer.js delete mode 100644 common/app/create-routes.js create mode 100644 common/app/files/index.js create mode 100644 common/app/reducer.js create mode 100644 common/app/routes-map.js rename common/app/routes/{challenges => Challenges}/Bug-Modal.jsx (97%) rename common/app/routes/{challenges => Challenges}/Challenge-Description.jsx (87%) rename common/app/routes/{challenges => Challenges}/Challenge-Title.jsx (90%) rename common/app/routes/{challenges => Challenges}/Code-Mirror-Skeleton.jsx (96%) rename common/app/routes/{challenges => Challenges}/Completion-Modal.jsx (96%) rename common/app/routes/{challenges => Challenges}/Output.jsx (91%) create mode 100644 common/app/routes/Challenges/Show.jsx rename common/app/routes/{challenges => Challenges}/Solution-Input.jsx (93%) rename common/app/routes/{challenges => Challenges}/Test-Suite.jsx (95%) rename common/app/routes/{challenges => Challenges}/challenges.less (100%) create mode 100644 common/app/routes/Challenges/index.js rename common/app/routes/{challenges => Challenges}/ns.json (100%) rename common/app/routes/{challenges => Challenges}/redux/bug-epic.js (97%) rename common/app/routes/{challenges => Challenges}/redux/challenge-epic.js (67%) rename common/app/routes/{challenges => Challenges}/redux/completion-epic.js (79%) rename common/app/routes/{challenges => Challenges}/redux/editor-epic.js (87%) rename common/app/routes/{challenges => Challenges}/redux/index.js (58%) rename common/app/routes/{challenges => Challenges}/utils.js (89%) rename common/app/routes/{challenges => Challenges}/utils.test.js (100%) rename common/app/routes/{challenges => Challenges}/views/backend/Back-End.jsx (98%) rename common/app/routes/{challenges => Challenges}/views/backend/Show.jsx (77%) rename common/app/routes/{challenges => Challenges}/views/backend/index.js (100%) rename common/app/routes/{challenges => Challenges}/views/classic/Editor.jsx (95%) rename common/app/routes/{challenges => Challenges}/views/classic/Preview.jsx (100%) rename common/app/routes/{challenges => Challenges}/views/classic/Show.jsx (63%) rename common/app/routes/{challenges => Challenges}/views/classic/Side-Panel.jsx (97%) rename common/app/routes/{challenges => Challenges}/views/classic/Tool-Panel.jsx (97%) rename common/app/routes/{challenges => Challenges}/views/classic/classic.less (100%) rename common/app/routes/{challenges => Challenges}/views/classic/index.js (100%) rename common/app/routes/{challenges => Challenges}/views/classic/ns.json (100%) rename common/app/routes/{challenges => Challenges}/views/index.less (100%) rename common/app/routes/{challenges => Challenges}/views/project/Forms.jsx (98%) rename common/app/routes/{challenges => Challenges}/views/project/Project.jsx (96%) rename common/app/routes/{challenges => Challenges}/views/project/Show.jsx (74%) rename common/app/routes/{challenges => Challenges}/views/project/Side-Panel.jsx (91%) rename common/app/routes/{challenges => Challenges}/views/project/Tool-Panel.jsx (97%) rename common/app/routes/{challenges => Challenges}/views/project/index.js (100%) rename common/app/routes/{challenges => Challenges}/views/project/ns.json (100%) rename common/app/routes/{challenges => Challenges}/views/project/redux/index.js (60%) rename common/app/routes/{challenges => Challenges}/views/project/redux/project-normalizer.js (100%) rename common/app/routes/{challenges => Challenges}/views/quiz/Choice.jsx (95%) rename common/app/routes/{challenges => Challenges}/views/quiz/Quiz.jsx (98%) rename common/app/routes/{challenges => Challenges}/views/quiz/Show.jsx (73%) rename common/app/routes/{challenges => Challenges}/views/quiz/index.js (100%) rename common/app/routes/{challenges => Challenges}/views/quiz/ns.json (100%) rename common/app/routes/{challenges => Challenges}/views/quiz/quiz.less (100%) rename common/app/routes/{challenges => Challenges}/views/quiz/redux/index.js (84%) rename common/app/routes/{challenges => Challenges}/views/step/Show.jsx (73%) rename common/app/routes/{challenges => Challenges}/views/step/Step.jsx (98%) rename common/app/routes/{challenges => Challenges}/views/step/index.js (100%) rename common/app/routes/{challenges => Challenges}/views/step/ns.json (100%) rename common/app/routes/{challenges => Challenges}/views/step/redux/index.js (89%) rename common/app/routes/{challenges => Challenges}/views/step/redux/step-challenge-epic.js (100%) rename common/app/routes/{challenges => Challenges}/views/step/redux/step-challenge-epic.test.js (95%) rename common/app/routes/{challenges => Challenges}/views/step/step.less (100%) create mode 100644 common/app/routes/Map/index.js rename common/app/routes/{settings => Settings}/Email-Setting.jsx (96%) rename common/app/routes/{settings => Settings}/Job-Settings.jsx (93%) rename common/app/routes/{settings => Settings}/Language-Settings.jsx (97%) rename common/app/routes/{settings => Settings}/Locked-Settings.jsx (93%) rename common/app/routes/{settings => Settings}/Settings-Skeleton.jsx (100%) rename common/app/routes/{settings => Settings}/Settings.jsx (99%) rename common/app/routes/{settings => Settings}/Social-Settings.jsx (96%) create mode 100644 common/app/routes/Settings/index.js rename common/app/routes/{settings => Settings}/ns.json (100%) create mode 100644 common/app/routes/Settings/redux/index.js rename common/app/routes/{settings => Settings}/redux/update-user-epic.js (97%) rename common/app/routes/{settings => Settings}/routes/update-email/Update-Email.jsx (94%) rename common/app/routes/{settings => Settings}/routes/update-email/index.js (100%) rename common/app/routes/{settings => Settings}/settings.less (100%) delete mode 100644 common/app/routes/challenges/Show.jsx delete mode 100644 common/app/routes/challenges/index.js delete mode 100644 common/app/routes/map/index.js delete mode 100644 common/app/routes/settings/index.js delete mode 100644 common/app/routes/settings/redux/index.js create mode 100644 common/app/utils/classic-file.js create mode 100644 common/app/utils/redux-first-router.js create mode 100644 common/utils/wait-for-epics.js create mode 100644 server/utils/react.js diff --git a/.babelrc b/.babelrc index 3554dc78e4..1bc508d704 100644 --- a/.babelrc +++ b/.babelrc @@ -1,4 +1,7 @@ { "presets": ["es2015", "react", "stage-0"], - "plugins": ["babel-plugin-add-module-exports"] + "plugins": [ + "babel-plugin-add-module-exports", + "lodash" + ] } diff --git a/.eslintrc b/.eslintrc index 1bad008c04..ea51953e9e 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,207 +1,3 @@ { - "parserOption": { - "ecmaVersion": 6, - "ecmaFeatures": { - "jsx": true - } - }, - "env": { - "es6": true, - "browser": true, - "mocha": true, - "node": true - }, - "parser": "babel-eslint", - "plugins": [ - "react", - "import", - "prefer-object-spread" - ], - "settings": { - "import/ignore": [ - "node_modules", - "\\.json$" - ], - "import/extensions": [ - ".js", - ".jsx" - ] - }, - "globals": { - "Promise": true, - "window": true, - "$": true, - "ga": true, - "jQuery": true, - "router": true - }, - "rules": { - "block-scoped-var": 0, - "brace-style": [ 2, "1tbs", { "allowSingleLine": true } ], - "camelcase": 2, - "comma-dangle": 2, - "comma-spacing": [ 2, { "before": false, "after": true } ], - "comma-style": [ 2, "last" ], - "complexity": 0, - "consistent-return": 2, - "consistent-this": 0, - "curly": 2, - "default-case": 2, - "dot-notation": 0, - "eol-last": 2, - "eqeqeq": 2, - "func-names": 0, - "func-style": 0, - "guard-for-in": 2, - "handle-callback-err": 2, - "jsx-quotes": [ 2, "prefer-single" ], - "key-spacing": [ 2, { "beforeColon": false, "afterColon": true } ], - "keyword-spacing": [ 2 ], - "max-depth": 0, - "max-len": [ 2, 80, 2 ], - "max-nested-callbacks": 0, - "max-params": 0, - "max-statements": 0, - "new-cap": 0, - "new-parens": 2, - "no-alert": 2, - "no-array-constructor": 2, - "no-bitwise": 2, - "no-caller": 2, - "no-catch-shadow": 2, - "no-cond-assign": 2, - "no-console": 0, - "no-constant-condition": 2, - "no-control-regex": 2, - "no-debugger": 2, - "no-delete-var": 2, - "no-div-regex": 2, - "no-dupe-keys": 2, - "no-else-return": 0, - "no-empty": 2, - "no-empty-character-class": 2, - "no-eq-null": 2, - "no-eval": 2, - "no-ex-assign": 2, - "no-extend-native": 2, - "no-extra-bind": 2, - "no-extra-boolean-cast": 2, - "no-extra-parens": 0, - "no-extra-semi": 2, - "no-fallthrough": 2, - "no-floating-decimal": 2, - "no-func-assign": 2, - "no-implied-eval": 2, - "no-inline-comments": 2, - "no-inner-declarations": 2, - "no-invalid-regexp": 2, - "no-irregular-whitespace": 2, - "no-iterator": 2, - "no-label-var": 2, - "no-labels": 2, - "no-lone-blocks": 2, - "no-lonely-if": 2, - "no-loop-func": 2, - "no-mixed-requires": 0, - "no-mixed-spaces-and-tabs": 2, - "no-multi-spaces": 2, - "no-multi-str": 2, - "no-multiple-empty-lines": [ 2, { "max": 2 } ], - "no-native-reassign": 2, - "no-negated-in-lhs": 2, - "no-nested-ternary": 2, - "no-new": 2, - "no-new-func": 2, - "no-new-object": 2, - "no-new-require": 2, - "no-new-wrappers": 2, - "no-obj-calls": 2, - "no-octal": 2, - "no-octal-escape": 2, - "no-path-concat": 2, - "no-plusplus": 0, - "no-process-env": 0, - "no-process-exit": 2, - "no-proto": 2, - "no-redeclare": 2, - "no-regex-spaces": 2, - "no-reserved-keys": 0, - "no-restricted-modules": 0, - "no-return-assign": 2, - "no-script-url": 2, - "no-self-compare": 2, - "no-sequences": 2, - "no-shadow": 0, - "no-shadow-restricted-names": 2, - "no-spaced-func": 2, - "no-sparse-arrays": 2, - "no-sync": 0, - "no-ternary": 0, - "no-trailing-spaces": 2, - "no-undef": 2, - "no-undef-init": 2, - "no-undefined": 2, - "no-underscore-dangle": 0, - "no-unreachable": 2, - "no-unused-expressions": 2, - "no-unused-vars": 2, - "no-use-before-define": 0, - "no-void": 0, - "no-warning-comments": [ 2, { "terms": [ "fixme" ], "location": "start" } ], - "no-with": 2, - "one-var": 0, - "operator-assignment": 0, - "padded-blocks": 0, - "quote-props": [ 2, "as-needed" ], - "quotes": [ 2, "single", "avoid-escape" ], - "radix": 2, - "semi": [ 2, "always" ], - "semi-spacing": [ 2, { "before": false, "after": true } ], - "sort-vars": 0, - "space-before-blocks": [ 2, "always" ], - "space-before-function-paren": [ 2, "never" ], - "space-in-brackets": 0, - "space-in-parens": 0, - "space-infix-ops": 2, - "space-unary-ops": [ 2, { "words": true, "nonwords": false } ], - "spaced-comment": [ 2, "always", { "exceptions": [ "-" ] } ], - "strict": 0, - "use-isnan": 2, - "valid-jsdoc": 2, - "valid-typeof": 2, - "vars-on-top": 0, - "wrap-iife": [ 2, "any" ], - "wrap-regex": 2, - "yoda": 0, - - "react/display-name": 2, - "react/jsx-boolean-value": [ 2, "always" ], - "react/jsx-closing-bracket-location": [ 2, { "selfClosing": "line-aligned", "nonEmpty": "props-aligned" } ], - "react/jsx-no-undef": 2, - "react/jsx-sort-props": [ 2, { "ignoreCase": true } ], - "react/jsx-uses-react": 2, - "react/jsx-uses-vars": 2, - "react/jsx-wrap-multilines": 2, - "react/no-did-mount-set-state": 2, - "react/no-did-update-set-state": 2, - "react/no-multi-comp": [ 2, { "ignoreStateless": true } ], - "react/no-unknown-property": 2, - "react/prop-types": 2, - "react/react-in-jsx-scope": 2, - "react/self-closing-comp": 2, - "react/sort-prop-types": 2, - - "import/default": 2, - "import/export": 2, - "import/extensions": [ 0, "always" ], - "import/first": 2, - "import/named": 2, - "import/namespace": 2, - "import/newline-after-import": 2, - "import/no-duplicates": 2, - "import/no-unresolved": 2, - "import/unambiguous": 2, - - "prefer-object-spread/prefer-object-spread": 2 - } + "extends": "freecodecamp" } diff --git a/client/epics/analytics-epic.js b/client/epics/analytics-epic.js index de4bfda5aa..da9207d167 100644 --- a/client/epics/analytics-epic.js +++ b/client/epics/analytics-epic.js @@ -27,7 +27,7 @@ function formatFields({ type, ...fields }) { }, { type }); } -export default function analyticsSaga(actions, { getState }, { window }) { +export default function analyticsSaga(actions, _, { window }) { const { ga } = window; if (typeof ga !== 'function') { console.log('GA not found'); diff --git a/client/epics/code-storage-epic.js b/client/epics/code-storage-epic.js index e48d8ef48a..eadbe740ef 100644 --- a/client/epics/code-storage-epic.js +++ b/client/epics/code-storage-epic.js @@ -7,20 +7,21 @@ import { removeCodeUri, getCodeUri } from '../utils/code-uri'; import { setContent } from '../../common/utils/polyvinyl'; import { + types as app, userSelector, challengeSelector } from '../../common/app/redux'; import { makeToast } from '../../common/app/Toasts/redux'; import { types, - savedCodeFound, updateMain, lockUntrustedCode, keySelector, - filesSelector, codeLockedSelector -} from '../../common/app/routes/challenges/redux'; +} from '../../common/app/routes/Challenges/redux'; + +import { filesSelector, savedCodeFound } from '../../common/app/files'; const legacyPrefixes = [ 'Bonfire: ', @@ -59,18 +60,19 @@ function legacyToFile(code, files, key) { } export function clearCodeEpic(actions, { getState }) { - return actions::ofType(types.clearSavedCode) - .map(() => { + return actions::ofType(types.submitChallenge.complete) + .do(() => { const { id } = challengeSelector(getState()); store.remove(id); }) .ignoreElements(); } + export function saveCodeEpic(actions, { getState }) { - return actions::ofType(types.saveCode) + return actions::ofType(types.executeChallenge) // do not save challenge if code is locked .filter(() => !codeLockedSelector(getState())) - .map(() => { + .do(() => { const { id } = challengeSelector(getState()); const files = filesSelector(getState()); store.set(id, files); @@ -79,7 +81,11 @@ export function saveCodeEpic(actions, { getState }) { } export function loadCodeEpic(actions, { getState }, { window, location }) { - return actions::ofType(types.loadCode) + return Observable.merge( + actions::ofType(app.appMounted), + actions::ofType(types.onRouteChallenges) + .distinctUntilChanged(({ payload: { dashedName } }) => dashedName) + ) .flatMap(() => { let finalFiles; const state = getState(); diff --git a/client/epics/execute-challenge-epic.js b/client/epics/execute-challenge-epic.js index 0fbf3a6886..d6da42b714 100644 --- a/client/epics/execute-challenge-epic.js +++ b/client/epics/execute-challenge-epic.js @@ -17,11 +17,11 @@ import { frameMain, frameTests, initOutput, - saveCode, - filesSelector, codeLockedSelector -} from '../../common/app/routes/challenges/redux'; +} from '../../common/app/routes/Challenges/redux'; + +import { filesSelector } from '../../common/app/files'; export default function executeChallengeEpic(actions, { getState }) { return actions::ofType(types.executeChallenge, types.updateMain) @@ -47,7 +47,7 @@ export default function executeChallengeEpic(actions, { getState }) { frameMain(payload) ]; if (type === types.executeChallenge) { - actions.push(saveCode(), frameTests(payload)); + actions.push(frameTests(payload)); } return Observable.from(actions, null, null, Scheduler.default); }) diff --git a/client/epics/frame-epic.js b/client/epics/frame-epic.js index 3d7c142940..b2ef3442fb 100644 --- a/client/epics/frame-epic.js +++ b/client/epics/frame-epic.js @@ -12,7 +12,7 @@ import { codeLockedSelector, testsSelector -} from '../../common/app/routes/challenges/redux'; +} from '../../common/app/routes/Challenges/redux'; // we use two different frames to make them all essentially pure functions // main iframe is responsible rendering the preview and is where we proxy the diff --git a/client/epics/hard-go-to-epic.js b/client/epics/hard-go-to-epic.js index b7850edfad..f485fa1276 100644 --- a/client/epics/hard-go-to-epic.js +++ b/client/epics/hard-go-to-epic.js @@ -1,7 +1,7 @@ import { types } from '../../common/app/redux'; import { ofType } from 'redux-epic'; -export default function hardGoToSaga(actions, { getState }, { history }) { +export default function hardGoToSaga(actions, _, { history }) { return actions::ofType(types.hardGoTo) .map(({ payload = '/settings' }) => { history.pushState(history.state, null, payload); diff --git a/client/epics/mouse-trap-epic.js b/client/epics/mouse-trap-epic.js index 72d4887e56..b5a6298d66 100644 --- a/client/epics/mouse-trap-epic.js +++ b/client/epics/mouse-trap-epic.js @@ -1,6 +1,6 @@ import { Observable } from 'rx'; import MouseTrap from 'mousetrap'; -import { push } from 'react-router-redux'; +import { push } from 'redux-first-router'; import { toggleNightMode, hardGoTo diff --git a/client/index.js b/client/index.js index 9bc7fbf57c..d67cd8f7b9 100644 --- a/client/index.js +++ b/client/index.js @@ -1,21 +1,13 @@ import './es6-shims'; import Rx from 'rx'; -import React from 'react'; import debug from 'debug'; -import { Router } from 'react-router'; -import { - routerMiddleware, - routerReducer as routing, - syncHistoryWithStore -} from 'react-router-redux'; import { render } from 'redux-epic'; -import { createHistory } from 'history'; +import createHistory from 'history/createBrowserHistory'; import useLangRoutes from './utils/use-lang-routes'; import sendPageAnalytics from './utils/send-page-analytics'; import flashToToast from './utils/flash-to-toast'; -import createApp from '../common/app'; -import provideStore from '../common/app/provide-store'; +import { App, createApp, provideStore } from '../common/app'; import { getLangFromPath } from '../common/app/utils/lang'; // client specific epics @@ -32,13 +24,13 @@ const log = debug('fcc:client'); const hotReloadTimeout = 2000; const { csrf: { token: csrfToken } = {} } = window.__fcc__; const DOMContainer = document.getElementById('fcc'); -const initialState = isColdStored() ? +const defaultState = isColdStored() ? getColdStorage() : window.__fcc__.data; const primaryLang = getLangFromPath(window.location.pathname); -initialState.app.csrfToken = csrfToken; -initialState.toasts = flashToToast(window.__fcc__.flash); +defaultState.app.csrfToken = csrfToken; +defaultState.toasts = flashToToast(window.__fcc__.flash); // make empty object so hot reload works window.__fcc__ = {}; @@ -49,7 +41,6 @@ const history = useLangRoutes(createHistory, primaryLang)(); sendPageAnalytics(history, window.ga); const devTools = window.devToolsExtension ? window.devToolsExtension() : f => f; -const adjustUrlOnReplay = !!window.devToolsExtension; const epicOptions = { isDev, @@ -61,14 +52,10 @@ const epicOptions = { createApp({ history, - syncHistoryWithStore, - syncOptions: { adjustUrlOnReplay }, serviceOptions, - initialState, - middlewares: [ routerMiddleware(history) ], + defaultState, epics, epicOptions, - reducers: { routing }, enhancers: [ devTools ] }) .doOnNext(({ store }) => { @@ -83,13 +70,7 @@ createApp({ } }) .doOnNext(() => log('rendering')) - .flatMap( - ({ props, store }) => render( - provideStore(React.createElement(Router, props), store), - DOMContainer - ), - ({ store }) => store - ) + .flatMap(({ store }) => render(provideStore(App, store), DOMContainer)) .subscribe( () => debug('react rendered'), err => { throw err; }, diff --git a/common/app/App.jsx b/common/app/App.jsx index 893d038f81..fa54b2fd28 100644 --- a/common/app/App.jsx +++ b/common/app/App.jsx @@ -1,29 +1,34 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import ns from './ns.json'; import { appMounted, fetchUser, - updateAppLang, - userSelector + isSignedInSelector } from './redux'; import Nav from './Nav'; import Toasts from './Toasts'; +import NotFound from './NotFound'; +import { mainRouteSelector } from './routes/redux'; +import Challenges from './routes/Challenges'; +import Settings from './routes/Settings'; const mapDispatchToProps = { appMounted, - fetchUser, - updateAppLang + fetchUser }; const mapStateToProps = state => { - const { username } = userSelector(state); + const isSignedIn = isSignedInSelector(state); + const route = mainRouteSelector(state); return { toast: state.app.toast, - isSignedIn: !!username + isSignedIn, + route }; }; @@ -32,19 +37,17 @@ const propTypes = { children: PropTypes.node, fetchUser: PropTypes.func, isSignedIn: PropTypes.bool, - params: PropTypes.object, - toast: PropTypes.object, - updateAppLang: PropTypes.func.isRequired + route: PropTypes.string, + toast: PropTypes.object +}; + +const routes = { + challenges: Challenges, + settings: Settings }; // export plain class for testing export class FreeCodeCamp extends React.Component { - componentWillReceiveProps(nextProps) { - if (this.props.params.lang !== nextProps.params.lang) { - this.props.updateAppLang(nextProps.params.lang); - } - } - componentDidMount() { this.props.appMounted(); if (!this.props.isSignedIn) { @@ -53,14 +56,18 @@ export class FreeCodeCamp extends React.Component { } render() { + const { + route + } = this.props; + const Child = routes[route] || NotFound; // we render nav after the content // to allow the panes to update // redux store, which will update the bin // buttons in the nav return (
- { this.props.children }
); diff --git a/common/app/Child-Container.jsx b/common/app/Child-Container.jsx index 5cbb95c85e..068b8170d1 100644 --- a/common/app/Child-Container.jsx +++ b/common/app/Child-Container.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import classnames from 'classnames'; import ns from './ns.json'; diff --git a/common/app/Map/Block.jsx b/common/app/Map/Block.jsx index 16e11ea83d..b71d70ce23 100644 --- a/common/app/Map/Block.jsx +++ b/common/app/Map/Block.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { createSelector } from 'reselect'; import FA from 'react-fontawesome'; diff --git a/common/app/Map/Challenge.jsx b/common/app/Map/Challenge.jsx index 5b9a544fd7..8e74dcf1b8 100644 --- a/common/app/Map/Challenge.jsx +++ b/common/app/Map/Challenge.jsx @@ -1,7 +1,7 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { createSelector } from 'reselect'; -import { Link } from 'react-router'; import PureComponent from 'react-pure-render/component'; import classnames from 'classnames'; import debug from 'debug'; @@ -13,6 +13,8 @@ import { } from './redux'; import { userSelector } from '../redux'; import { challengeMapSelector } from '../entities'; +import { Link } from '../Router'; +import { onRouteChallenges } from '../routes/Challenges/redux'; const propTypes = { block: PropTypes.string, @@ -27,15 +29,7 @@ const propTypes = { isRequired: PropTypes.bool, title: PropTypes.string }; -function mapDispatchToProps(dispatch, { dashedName }) { - const dispatchers = { - clickOnChallenge: e => { - e.preventDefault(); - return dispatch(clickOnChallenge(dashedName)); - } - }; - return () => dispatchers; -} +const mapDispatchToProps = { clickOnChallenge }; function makeMapStateToProps(_, { dashedName }) { return createSelector( @@ -152,8 +146,11 @@ export class Challenge extends PureComponent { className={ challengeClassName } key={ title } > - - + + { title } { this.renderCompleted(isCompleted, isLocked) } { this.renderRequired(isRequired) } diff --git a/common/app/Map/Map.jsx b/common/app/Map/Map.jsx index 28c32c07ef..83a99c6043 100644 --- a/common/app/Map/Map.jsx +++ b/common/app/Map/Map.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import PureComponent from 'react-pure-render/component'; import { Col, Row } from 'react-bootstrap'; diff --git a/common/app/Map/Super-Block.jsx b/common/app/Map/Super-Block.jsx index c112f620da..8a82f1a7f5 100644 --- a/common/app/Map/Super-Block.jsx +++ b/common/app/Map/Super-Block.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { createSelector } from 'reselect'; import PureComponent from 'react-pure-render/component'; diff --git a/common/app/Map/redux/index.js b/common/app/Map/redux/index.js index 6c6bc452d6..73bbaa7bac 100644 --- a/common/app/Map/redux/index.js +++ b/common/app/Map/redux/index.js @@ -1,11 +1,12 @@ -import { createTypes } from 'redux-create-types'; -import { createAction, handleActions } from 'redux-actions'; +import { + createAction, + createTypes, + handleActions +} from 'berkeleys-redux-utils'; import { createSelector } from 'reselect'; -import identity from 'lodash/identity'; +import noop from 'lodash/noop'; import capitalize from 'lodash/capitalize'; -import selectChallengeEpic from './select-challenge-epic.js'; - import * as utils from './utils.js'; import ns from '../ns.json'; import { @@ -13,11 +14,10 @@ import { createEventMetaCreator } from '../../redux'; -export const epics = [ - selectChallengeEpic -]; +export const epics = []; export const types = createTypes([ + 'onRouteMap', 'initMap', 'toggleThisPanel', @@ -37,7 +37,7 @@ export const collapseAll = createAction(types.collapseAll); export const expandAll = createAction(types.expandAll); export const clickOnChallenge = createAction( types.clickOnChallenge, - identity, + noop, createEventMetaCreator({ category: capitalize(ns), action: 'click', @@ -88,42 +88,38 @@ export function makePanelHiddenSelector(name) { // }] // } // } -export default function createReducer() { - const reducer = handleActions( - { - [types.toggleThisPanel]: (state, { payload: name }) => { - return { - ...state, - mapUi: utils.toggleThisPanel(state.mapUi, name) - }; - }, - [types.collapseAll]: state => { - const mapUi = utils.collapseAllPanels(state.mapUi); - mapUi.isAllCollapsed = true; - return { - ...state, - mapUi - }; - }, - [types.expandAll]: state => { - const mapUi = utils.expandAllPanels(state.mapUi); - mapUi.isAllCollapsed = false; - return { - ...state, - mapUi - }; - }, - [app.fetchChallenges.complete]: (state, { payload }) => { - const { entities, result } = payload; - return { - ...state, - mapUi: utils.createMapUi(entities, result) - }; - } +export default handleActions( + ()=> ({ + [types.toggleThisPanel]: (state, { payload: name }) => { + return { + ...state, + mapUi: utils.toggleThisPanel(state.mapUi, name) + }; }, - initialState - ); - - reducer.toString = () => ns; - return reducer; -} + [types.collapseAll]: state => { + const mapUi = utils.collapseAllPanels(state.mapUi); + mapUi.isAllCollapsed = true; + return { + ...state, + mapUi + }; + }, + [types.expandAll]: state => { + const mapUi = utils.expandAllPanels(state.mapUi); + mapUi.isAllCollapsed = false; + return { + ...state, + mapUi + }; + }, + [app.fetchChallenges.complete]: (state, { payload }) => { + const { entities, result } = payload; + return { + ...state, + mapUi: utils.createMapUi(entities, result) + }; + } + }), + initialState, + ns +); diff --git a/common/app/Map/redux/select-challenge-epic.js b/common/app/Map/redux/select-challenge-epic.js deleted file mode 100644 index 090bc019cf..0000000000 --- a/common/app/Map/redux/select-challenge-epic.js +++ /dev/null @@ -1,10 +0,0 @@ -import { ofType } from 'redux-epic'; - -import { types } from './'; -import { updateCurrentChallenge } from '../../redux'; - -export default function selectChallengeEpic(actions) { - return actions::ofType(types.clickOnChallenge) - .pluck('payload') - .map(updateCurrentChallenge); -} diff --git a/common/app/Nav/Bin-Button.jsx b/common/app/Nav/Bin-Button.jsx index 47d822f316..21360d4cdf 100644 --- a/common/app/Nav/Bin-Button.jsx +++ b/common/app/Nav/Bin-Button.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import { NavItem } from 'react-bootstrap'; const propTypes = { diff --git a/common/app/Nav/Nav.jsx b/common/app/Nav/Nav.jsx index 3c550fb27c..7502a9b1f5 100644 --- a/common/app/Nav/Nav.jsx +++ b/common/app/Nav/Nav.jsx @@ -1,10 +1,10 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import capitalize from 'lodash/capitalize'; import { createSelector } from 'reselect'; -import { LinkContainer } from 'react-router-bootstrap'; import { MenuItem, Nav, @@ -14,6 +14,7 @@ import { NavbarBrand } from 'react-bootstrap'; +import { Link } from '../Router'; import navLinks from './links.json'; import SignUp from './Sign-Up.jsx'; import BinButton from './Bin-Button.jsx'; @@ -28,35 +29,36 @@ import { } from './redux'; import { userSelector, + isSignedInSelector, signInLoadingSelector } from '../redux'; -import { nameToTypeSelector, panesSelector } from '../Panes/redux'; +import { panesSelector } from '../Panes/redux'; const fCClogo = 'https://s3.amazonaws.com/freecodecamp/freecodecamp_logo.svg'; const mapStateToProps = createSelector( userSelector, + isSignedInSelector, dropdownSelector, signInLoadingSelector, panesSelector, - nameToTypeSelector, ( { username, picture, points }, + isSignedIn, isDropdownOpen, showLoading, panes, - nameToType ) => { return { - panes: panes.map(name => { + panes: panes.map(({ name, type }) => { return { content: name, - action: nameToType[name] + action: type }; }, {}), isDropdownOpen, - isSignedIn: !!username, + isSignedIn, picture, points, showLoading, @@ -104,25 +106,19 @@ function mergeProps(stateProps, dispatchProps, ownProps) { }; } -const propTypes = navLinks.reduce( - (pt, { content }) => { - const handler = `handle${capitalize(content)}Click`; - pt[handler] = PropTypes.func.isRequired; - return pt; - }, - { - panes: PropTypes.array, - clickOnLogo: PropTypes.func.isRequired, - closeDropdown: PropTypes.func.isRequired, - isDropdownOpen: PropTypes.bool, - openDropdown: PropTypes.func.isRequired, - picture: PropTypes.string, - points: PropTypes.number, - showLoading: PropTypes.bool, - signedIn: PropTypes.bool, - username: PropTypes.string - } -); +const propTypes = { + clickOnLogo: PropTypes.func.isRequired, + clickOnMap: PropTypes.func.isRequired, + closeDropdown: PropTypes.func.isRequired, + isDropdownOpen: PropTypes.bool, + openDropdown: PropTypes.func.isRequired, + panes: PropTypes.array, + picture: PropTypes.string, + points: PropTypes.number, + showLoading: PropTypes.bool, + signedIn: PropTypes.bool, + username: PropTypes.string +}; export class FCCNav extends React.Component { renderLink(isNavItem, { isReact, isDropdown, content, link, links, target }) { @@ -154,7 +150,7 @@ export class FCCNav extends React.Component { } if (isReact) { return ( - { content } - + ); } return ( diff --git a/common/app/Nav/Sign-Up.jsx b/common/app/Nav/Sign-Up.jsx index 2676d8fd3b..63004fe16a 100644 --- a/common/app/Nav/Sign-Up.jsx +++ b/common/app/Nav/Sign-Up.jsx @@ -1,7 +1,10 @@ -import React, { PropTypes } from 'react'; -import { Link } from 'react-router'; +import React from 'react'; +import PropTypes from 'prop-types'; import { NavItem } from 'react-bootstrap'; +import { Link } from '../Router'; +import { onRouteSettings } from '../routes/Settings/redux'; + // this is separated out to prevent react bootstrap's // NavBar from injecting unknown props to the li component @@ -36,7 +39,7 @@ export default function SignUpButton({ className='nav-avatar' key='user' > - + { username } [ { points || 1 } ] diff --git a/common/app/Nav/redux/index.js b/common/app/Nav/redux/index.js index f6fd626085..297d859434 100644 --- a/common/app/Nav/redux/index.js +++ b/common/app/Nav/redux/index.js @@ -1,7 +1,10 @@ import capitalize from 'lodash/capitalize'; -import { createTypes } from 'redux-create-types'; -import { createAction, handleActions } from 'redux-actions'; import noop from 'lodash/noop'; +import { + createAction, + createTypes, + handleActions +} from 'berkeleys-redux-utils'; import loadCurrentChallengeEpic from './load-current-challenge-epic.js'; import binEpic from './bin-epic.js'; @@ -62,8 +65,8 @@ const initialState = { export const dropdownSelector = state => state[ns].isDropdownOpen; -export default function createReducer() { - const reducer = handleActions({ +export default handleActions( + () => ({ [types.closeDropdown]: state => ({ ...state, isDropdownOpen: false @@ -72,8 +75,7 @@ export default function createReducer() { ...state, isDropdownOpen: true }) - }, initialState); - - reducer.toString = () => ns; - return reducer; -} + }), + initialState, + ns +); diff --git a/common/app/Nav/redux/load-current-challenge-epic.js b/common/app/Nav/redux/load-current-challenge-epic.js index 52efe9352f..066bf5986f 100644 --- a/common/app/Nav/redux/load-current-challenge-epic.js +++ b/common/app/Nav/redux/load-current-challenge-epic.js @@ -2,12 +2,11 @@ import { ofType } from 'redux-epic'; import { types } from './'; import { - updateCurrentChallenge, - userSelector, firstChallengeSelector, challengeSelector } from '../../redux'; +import { onRouteChallenges } from '../../routes/Challenges/redux'; import { entitiesSelector } from '../../entities'; export default function loadCurrentChallengeEpic(actions, { getState }) { @@ -55,7 +54,5 @@ export default function loadCurrentChallengeEpic(actions, { getState }) { // don't reload if the challenge is already loaded. // This may change to toast to avoid user confusion )) - .map(({ finalChallenge }) => { - return updateCurrentChallenge(finalChallenge.dashedName); - }); + .map(({ finalChallenge }) => onRouteChallenges(finalChallenge)); } diff --git a/common/app/NotFound/Not-Found.jsx b/common/app/NotFound/Not-Found.jsx index f8223a9357..13c796137d 100644 --- a/common/app/NotFound/Not-Found.jsx +++ b/common/app/NotFound/Not-Found.jsx @@ -1,23 +1,15 @@ -import React, { PropTypes } from 'react'; -import { connect } from 'react-redux'; -import { hardGoTo } from '../redux'; +import React from 'react'; -const propTypes = { - hardGoTo: PropTypes.func, - location: PropTypes.object -}; +// import PropTypes from 'prop-types'; -export class NotFound extends React.Component { - componentWillMount() { - this.props.hardGoTo(this.props.location.pathname); - } +const propTypes = {}; - render() { - return ; - } +export default function NotFound() { + return ( +
404 Not Found
+ ); } NotFound.displayName = 'NotFound'; NotFound.propTypes = propTypes; -export default connect(null, { hardGoTo })(NotFound); diff --git a/common/app/Panes/Divider.jsx b/common/app/Panes/Divider.jsx index 3eb97df6b0..a90fd88775 100644 --- a/common/app/Panes/Divider.jsx +++ b/common/app/Panes/Divider.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { dividerClicked } from './redux'; diff --git a/common/app/Panes/Pane.jsx b/common/app/Panes/Pane.jsx index dee72c5da6..15f95a4c64 100644 --- a/common/app/Panes/Pane.jsx +++ b/common/app/Panes/Pane.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import { connect } from 'react-redux'; const mapStateToProps = null; diff --git a/common/app/Panes/Panes-Container.jsx b/common/app/Panes/Panes-Container.jsx index cec7878bcd..cf5bfbbe10 100644 --- a/common/app/Panes/Panes-Container.jsx +++ b/common/app/Panes/Panes-Container.jsx @@ -1,48 +1,24 @@ -import React, { PureComponent, PropTypes } from 'react'; +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import Panes from './Panes.jsx'; -import { - panesMounted, - panesUpdated, - panesWillMount, - panesWillUnmount -} from './redux'; +import { panesMounted } from './redux'; const mapStateToProps = null; const mapDispatchToProps = { - panesMounted, - panesUpdated, - panesWillMount, - panesWillUnmount + panesMounted }; const propTypes = { nameToComponent: PropTypes.object.isRequired, - panesMounted: PropTypes.func.isRequired, - panesUpdated: PropTypes.func.isRequired, - panesWillMount: PropTypes.func.isRequired, - panesWillUnmount: PropTypes.func.isRequired + panesMounted: PropTypes.func.isRequired }; export class PanesContainer extends PureComponent { - componentWillMount() { - this.props.panesWillMount(Object.keys(this.props.nameToComponent)); - } componentDidMount() { this.props.panesMounted(); } - - componentWillUnmount() { - this.props.panesWillUnmount(); - } - - componentWillReceiveProps(nextProps) { - if (nextProps.nameToComponent !== this.props.nameToComponent) { - this.props.panesUpdated(Object.keys(nextProps.nameToComponent)); - } - } - render() { return ( diff --git a/common/app/Panes/Panes.jsx b/common/app/Panes/Panes.jsx index 2bc7d9a2f4..df8133fb07 100644 --- a/common/app/Panes/Panes.jsx +++ b/common/app/Panes/Panes.jsx @@ -1,4 +1,5 @@ -import React, { PureComponent, PropTypes } from 'react'; +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { createSelector } from 'reselect'; @@ -20,7 +21,7 @@ const mapStateToProps = createSelector( let lastDividerPosition = 0; return { panes: panes - .map(name => panesByName[name]) + .map(({ name }) => panesByName[name]) .filter(({ isHidden })=> !isHidden) .map((pane, index, { length: numOfPanes }) => { const dividerLeft = pane.dividerLeft || 0; diff --git a/common/app/Panes/redux/index.js b/common/app/Panes/redux/index.js index ad4e608b1b..d5254d5cb3 100644 --- a/common/app/Panes/redux/index.js +++ b/common/app/Panes/redux/index.js @@ -1,11 +1,18 @@ -import { combineActions, createAction, handleActions } from 'redux-actions'; -import { createTypes } from 'redux-create-types'; -import clamp from 'lodash/clamp'; +import { isLocationAction } from 'redux-first-router'; +import _ from 'lodash'; +import { + composeReducers, + createAction, + createTypes, + handleActions +} from 'berkeleys-redux-utils'; import ns from '../ns.json'; import windowEpic from './window-epic.js'; import dividerEpic from './divider-epic.js'; +import { challengeMetaSelector } from '../../routes/Challenges/redux'; +import { types as app } from '../../redux'; const isDev = process.env.NODE_ENV !== 'production'; export const epics = [ @@ -14,6 +21,7 @@ export const epics = [ ]; export const types = createTypes([ + 'panesUpdatedThroughFetch', 'panesMounted', 'panesUpdated', 'panesWillMount', @@ -30,6 +38,11 @@ export const types = createTypes([ 'hidePane' ], ns); +export const panesUpdatedThroughFetch = createAction( + types.panesUpdatedThroughFetch, + null, + panesView => ({ panesView }) +); export const panesMounted = createAction(types.panesMounted); export const panesUpdated = createAction(types.panesUpdated); export const panesWillMount = createAction(types.panesWillMount); @@ -78,9 +91,45 @@ function getDividerLeft(numOfPanes, index) { return dividerLeft; } -export default function createPanesAspects(typeToName) { +function forEachConfig(config, cb) { + return _.forEach(config, (val, key) => { + // val is a sub config + if (_.isObject(val) && !val.name) { + return forEachConfig(val, cb); + } + return cb(config, key); + }); +} + +function reduceConfig(config, cb, acc = {}) { + return _.reduce(config, (acc, val, key) => { + if (_.isObject(val) && !val.name) { + return reduceConfig(val, cb, acc); + } + return cb(acc, val, key); + }, acc); +} + +const getPaneName = (panes, index) => (panes[index] || {}).name || ''; + +export const createPaneMap = (ns, getPanesMap) => { + const panesMap = _.reduce(getPanesMap(), (map, val, key) => { + let paneConfig = val; + if (typeof val === 'string') { + paneConfig = { + name: val + }; + } + map[key] = paneConfig; + return map; + }, {}); + return Object.defineProperty(panesMap, 'toString', { value: () => ns }); +}; + + +export default function createPanesAspects(config) { if (isDev) { - Object.keys(typeToName).forEach(actionType => { + forEachConfig(config, (typeToName, actionType) => { if (actionType === 'undefined') { throw new Error( `action type for ${typeToName[actionType]} is undefined` @@ -88,18 +137,24 @@ export default function createPanesAspects(typeToName) { } }); } - const nameToType = Object.keys(typeToName).reduce((map, type) => { - map[typeToName[type]] = type; - return map; - }, {}); - function getInitialState() { - return { - ...initialState, - nameToType - }; - } + const typeToName = reduceConfig(config, (acc, val, type) => { + const name = _.isObject(val) ? val.name : val; + acc[type] = name; + return acc; + }); - function middleware() { + function middleware({ getState }) { + const filterPanes = panesMap => _.reduce(panesMap, (panes, pane, type) => { + if (typeof pane.filter !== 'function' || pane.filter(getState())) { + panes[type] = pane; + } + return panes; + }, {}); + // we cache the previous map so that we can attach it to the fetchChallenge + let previousMap; + // show panes on challenge route + // select panes map on viewType (this is state dependent) + // filter panes out on state return next => action => { let finalAction = action; if (isPanesAction(action, typeToName)) { @@ -107,130 +162,150 @@ export default function createPanesAspects(typeToName) { ...action, meta: { ...action.meta, - isPaneAction: true + isPaneAction: true, + paneName: typeToName[action.type] } }; } - return next(finalAction); + const result = next(finalAction); + if (isLocationAction(action)) { + // location matches a panes route + if (config[action.type]) { + const paneMap = previousMap = config[action.type]; + const meta = challengeMetaSelector(getState()); + const viewMap = paneMap[meta.viewType] || {}; + next(panesUpdatedThroughFetch(filterPanes(viewMap))); + } else { + next(panesUpdatedThroughFetch({})); + } + } + if (action.type === app.fetchChallenge.complete) { + const meta = challengeMetaSelector(getState()); + const viewMap = previousMap[meta.viewType] || {}; + next(panesUpdatedThroughFetch(filterPanes(viewMap))); + } + return result; }; } - const reducer = handleActions({ - [types.dividerClicked]: (state, { payload: name }) => ({ - ...state, - pressedDivider: name - }), - [types.dividerMoved]: (state, { payload: clientX }) => { - const { width, pressedDivider: paneName } = state; - const dividerBuffer = (200 / width) * 100; - const paneIndex = state.panes.indexOf(paneName); - const currentPane = state.panesByName[paneName]; - const rightPane = state.panesByName[state.panes[paneIndex + 1]] || {}; - const leftPane = state.panesByName[state.panes[paneIndex - 1]] || {}; - const rightBound = (rightPane.dividerLeft || 100) - dividerBuffer; - const leftBound = (leftPane.dividerLeft || 0) + dividerBuffer; - const newPosition = clamp( - (clientX / width) * 100, - leftBound, - rightBound - ); - return { - ...state, - panesByName: { - ...state.panesByName, - [currentPane.name]: { - ...currentPane, - dividerLeft: newPosition - } - } - }; - }, - [types.mouseReleased]: state => ({ ...state, pressedDivider: null }), - [types.windowResized]: (state, { payload: { height, width } }) => ({ - ...state, - height, - width - }), - // used to clear bin buttons - [types.panesWillUnmount]: state => ({ - ...state, - panes: [], - panesByName: {}, - pressedDivider: null - }), - [ - combineActions( - panesWillMount, - panesUpdated - ) - ]: (state, { payload: panes }) => { - const numOfPanes = panes.length; - return { - ...state, - panes, - panesByName: panes.reduce((panes, name, index) => { - const dividerLeft = getDividerLeft(numOfPanes, index); - panes[name] = { - name, - dividerLeft, - isHidden: false - }; - return panes; - }, {}) - }; - }, - [types.updateNavHeight]: (state, { payload: navHeight }) => ({ - ...state, - navHeight - }) - }, getInitialState()); - function metaReducer(state = getInitialState(), action) { - if (action.meta && action.meta.isPaneAction) { - const name = typeToName[action.type]; - const oldPane = state.panesByName[name]; - const pane = { - ...oldPane, - isHidden: !oldPane.isHidden - }; - const panesByName = { - ...state.panesByName, - [name]: pane - }; - const numOfPanes = state.panes.reduce((sum, name) => { - return panesByName[name].isHidden ? sum : sum + 1; - }, 0); - let numOfHidden = 0; - return { - ...state, - panesByName: state.panes.reduce( - (panesByName, name, index) => { - if (!panesByName[name].isHidden) { - const dividerLeft = getDividerLeft( - numOfPanes, - index - numOfHidden - ); - panesByName[name] = { - ...panesByName[name], - dividerLeft - }; - } else { - numOfHidden = numOfHidden + 1; + const reducer = composeReducers( + ns, + handleActions( + () => ({ + [types.dividerClicked]: (state, { payload: name }) => ({ + ...state, + pressedDivider: name + }), + [types.dividerMoved]: (state, { payload: clientX }) => { + const { width, pressedDivider: paneName } = state; + const dividerBuffer = (200 / width) * 100; + const paneIndex = + _.findIndex(state.panes, ({ name }) => paneName === name); + const currentPane = state.panesByName[paneName]; + const rightPane = + state.panesByName[getPaneName(state.panes, paneIndex + 1)] || {}; + const leftPane = + state.panesByName[getPaneName(state.panes, paneIndex - 1)] || {}; + const rightBound = (rightPane.dividerLeft || 100) - dividerBuffer; + const leftBound = (leftPane.dividerLeft || 0) + dividerBuffer; + const newPosition = _.clamp( + (clientX / width) * 100, + leftBound, + rightBound + ); + return { + ...state, + panesByName: { + ...state.panesByName, + [currentPane.name]: { + ...currentPane, + dividerLeft: newPosition + } } - return panesByName; - }, - panesByName - ) - }; + }; + }, + [types.mouseReleased]: state => ({ ...state, pressedDivider: null }), + [types.windowResized]: (state, { payload: { height, width } }) => ({ + ...state, + height, + width + }), + // used to clear bin buttons + [types.panesWillUnmount]: state => ({ + ...state, + panes: [], + panesByName: {}, + pressedDivider: null + }), + [types.updateNavHeight]: (state, { payload: navHeight }) => ({ + ...state, + navHeight + }) + }), + initialState, + ), + function metaReducer(state = initialState, action) { + if (action.meta && action.meta.panesView) { + const panesView = action.meta.panesView; + const panes = _.map(panesView, ({ name }, type) => ({ name, type })); + const numOfPanes = Object.keys(panes).length; + return { + ...state, + panes, + panesByName: panes.reduce((panes, { name }, index) => { + const dividerLeft = getDividerLeft(numOfPanes, index); + panes[name] = { + name, + dividerLeft, + isHidden: false + }; + return panes; + }, {}) + }; + } + if (action.meta && action.meta.isPaneAction) { + const name = action.meta.paneName; + const oldPane = state.panesByName[name]; + const pane = { + ...oldPane, + isHidden: !oldPane.isHidden + }; + const panesByName = { + ...state.panesByName, + [name]: pane + }; + const numOfPanes = state.panes.reduce((sum, { name }) => { + return panesByName[name].isHidden ? sum : sum + 1; + }, 0); + let numOfHidden = 0; + return { + ...state, + panesByName: state.panes.reduce( + (panesByName, { name }, index) => { + if (!panesByName[name].isHidden) { + const dividerLeft = getDividerLeft( + numOfPanes, + index - numOfHidden + ); + panesByName[name] = { + ...panesByName[name], + dividerLeft + }; + } else { + numOfHidden = numOfHidden + 1; + } + return panesByName; + }, + panesByName + ) + }; + } + return state; } - return state; - } + ); - function finalReducer(state, action) { - return reducer(metaReducer(state, action), action); - } - finalReducer.toString = () => ns; return { - reducer: finalReducer, + reducer, middleware }; } diff --git a/common/app/Router/Link.jsx b/common/app/Router/Link.jsx new file mode 100644 index 0000000000..9f6b906ec0 --- /dev/null +++ b/common/app/Router/Link.jsx @@ -0,0 +1,80 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import { selectLocationState } from 'redux-first-router'; + +import toUrl from './to-url.js'; +import createHandler from './handle-press.js'; +import { langSelector } from './redux'; + +const propTypes = { + children: PropTypes.node, + dispatch: PropTypes.func, + onClick: PropTypes.func, + redirect: PropTypes.bool, + replace: PropTypes.bool, + shouldDispatch: PropTypes.bool, + target: PropTypes.string, + to: PropTypes.oneOfType([ PropTypes.object, PropTypes.string ]).isRequired +}; + +export const Link = ( + { + children, + dispatch, + onClick, + redirect, + replace, + shouldDispatch = true, + target, + to + }, + { store } +) => { + const state = store.getState(); + const lang = langSelector(state); + const location = selectLocationState(state); + const { routesMap } = location; + const url = toUrl(to, routesMap, lang); + const handler = createHandler( + url, + routesMap, + onClick, + shouldDispatch, + target, + dispatch, + to, + replace || redirect + ); + + const localProps = {}; + + if (url) { + localProps.href = url; + } + + if (handler) { + localProps.onMouseDown = handler; + localProps.onTouchStart = handler; + } + + if (target) { + localProps.target = target; + } + + return ( + + {children} + + ); +}; + +Link.contextTypes = { + store: PropTypes.object.isRequired +}; +Link.propTypes = propTypes; + +export default connect()(Link); diff --git a/common/app/Router/handle-press.js b/common/app/Router/handle-press.js new file mode 100644 index 0000000000..5cda85860d --- /dev/null +++ b/common/app/Router/handle-press.js @@ -0,0 +1,50 @@ +import { pathToAction, redirect, getOptions } from 'redux-first-router'; + +const isAction = to => typeof to === 'object' && + !Array.isArray(to); + +const isModified = e => !!( + e.metaKey || + e.altKey || + e.ctrlKey || + e.shiftKey +); + +export default ( + url, + routesMap, + onClick, + shouldDispatch, + target, + dispatch, + to, + dispatchRedirect +) => e => { + let shouldGo = true; + + if (onClick) { + // onClick can return false to prevent dispatch + shouldGo = onClick(e); + shouldGo = typeof shouldGo === 'undefined' ? true : shouldGo; + } + + const prevented = e.defaultPrevented; + + if (!target && e && e.preventDefault && !isModified(e)) { + e.preventDefault(); + } + + if ( + shouldGo && + shouldDispatch && + !target && + !prevented && + e.button === 0 && + !isModified(e) + ) { + const { querySerializer: serializer } = getOptions(); + let action = isAction(to) ? to : pathToAction(url, routesMap, serializer); + action = dispatchRedirect ? redirect(action) : action; + dispatch(action); + } +}; diff --git a/common/app/Router/index.js b/common/app/Router/index.js new file mode 100644 index 0000000000..79f148eac7 --- /dev/null +++ b/common/app/Router/index.js @@ -0,0 +1 @@ +export { default as Link } from './Link.jsx'; diff --git a/common/app/Router/redux/add-lang-enhancer.js b/common/app/Router/redux/add-lang-enhancer.js new file mode 100644 index 0000000000..476af0af82 --- /dev/null +++ b/common/app/Router/redux/add-lang-enhancer.js @@ -0,0 +1,28 @@ +import { langSelector } from './'; + +// This enhancers sole purpose is to add the lang prop to route actions so that +// they do not need to be explicitally added when using a RFR route action. +export default function addLangToRouteEnhancer(routesMap) { + return createStore => (...args) => { + const store = createStore(...args); + + return { + ...store, + dispatch(action) { + if ( + routesMap[action.type] && + (action && action.payload && !action.payload.lang) + ) { + action = { + ...action, + payload: { + ...action.payload, + lang: langSelector(store.getState()) || 'en' + } + }; + } + return store.dispatch(action); + } + }; + }; +} diff --git a/common/app/Router/redux/index.js b/common/app/Router/redux/index.js new file mode 100644 index 0000000000..2959893d1f --- /dev/null +++ b/common/app/Router/redux/index.js @@ -0,0 +1,5 @@ +import { selectLocationState } from 'redux-first-router'; + +export const paramsSelector = state => selectLocationState(state).payload || {}; +export const langSelector = state => paramsSelector(state).lang || 'en'; +export const routesMapSelector = state => paramsSelector(state).routesMap || {}; diff --git a/common/app/Router/to-url.js b/common/app/Router/to-url.js new file mode 100644 index 0000000000..b436859b8c --- /dev/null +++ b/common/app/Router/to-url.js @@ -0,0 +1,45 @@ +import { actionToPath, getOptions } from 'redux-first-router'; + +import { addLang } from '../utils/lang.js'; + + +export default (to, routesMap, lang = 'en') => { + if (to && typeof to === 'string') { + return addLang(to, lang); + } + + if (typeof to === 'object') { + const { payload = {}, ...action } = to; + + try { + const { querySerializer } = getOptions(); + return actionToPath( + { + ...action, + payload: { + ...payload, + lang: payload.lang || lang + } + }, + routesMap, + querySerializer + ); + } catch (e) { + console.error(e); + console.warn( + '[Link] could not create path from action:', + action, + 'For reference, here are your current routes:', + routesMap + ); + + return '#'; + } + } + + console.warn( + '[Link] `to` prop must be a string or action object. You provided: ', + to + ); + return '#'; +}; diff --git a/common/app/Toasts/Toasts.jsx b/common/app/Toasts/Toasts.jsx index 8e55ae9ac0..d81f813afc 100644 --- a/common/app/Toasts/Toasts.jsx +++ b/common/app/Toasts/Toasts.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { createSelector } from 'reselect'; import { NotificationStack } from 'react-notification'; @@ -6,12 +7,12 @@ import { NotificationStack } from 'react-notification'; import { removeToast } from './redux'; import { submitChallenge, - resetChallenge -} from '../routes/challenges/redux'; + clickOnReset +} from '../routes/Challenges/redux'; const registeredActions = { submitChallenge, - resetChallenge + clickOnReset }; const mapStateToProps = state => ({ toasts: state.toasts }); // we use styles here to overwrite those built into the library diff --git a/common/app/Toasts/redux/index.js b/common/app/Toasts/redux/index.js index af05b57b1f..e8cdccec87 100644 --- a/common/app/Toasts/redux/index.js +++ b/common/app/Toasts/redux/index.js @@ -1,12 +1,15 @@ -import { createTypes } from 'redux-create-types'; -import { createAction, handleActions } from 'redux-actions'; +import { + createAction, + createTypes, + handleActions +} from 'berkeleys-redux-utils'; import ns from '../ns.json'; export const types = createTypes([ 'makeToast', 'removeToast' -], 'toast'); +], ns); let key = 0; export const makeToast = createAction( @@ -29,8 +32,8 @@ export const removeToast = createAction( const initialState = []; -export default function createReducer() { - const reducer = handleActions({ +export default handleActions( + () => ({ [types.makeToast]: (state, { payload: toast }) => [ ...state, toast @@ -38,8 +41,7 @@ export default function createReducer() { [types.removeToast]: (state, { payload: key }) => state.filter( toast => toast.key !== key ) - }, initialState); - - reducer.toString = () => ns; - return reducer; -} + }), + initialState, + ns +); diff --git a/common/app/app.less b/common/app/app.less index e49c32c903..100910c75f 100644 --- a/common/app/app.less +++ b/common/app/app.less @@ -7,7 +7,7 @@ // Here we invert the order in which // they are painted using css so the // nav is on top again - .grid(@direction: column-reverse); + .grid(@direction: column); } .@{ns}-content { diff --git a/common/app/create-app.jsx b/common/app/create-app.jsx index efb77b269e..0cd505ac8f 100644 --- a/common/app/create-app.jsx +++ b/common/app/create-app.jsx @@ -1,42 +1,35 @@ import { Observable } from 'rx'; -import { match } from 'react-router'; import { compose, createStore, applyMiddleware } from 'redux'; +import { selectLocationState, connectRoutes } from 'redux-first-router'; +import { combineReducers } from 'berkeleys-redux-utils'; import { createEpic } from 'redux-epic'; -import createReducer from './create-reducer'; -import createRoutes from './create-routes.js'; +import appReducer from './reducer.js'; +import routesMap from './routes-map.js'; import createPanesMap from './create-panes-map.js'; import createPanesAspects from './Panes/redux'; +import addLangToRoutesEnhancer from './Router/redux/add-lang-enhancer.js'; import epics from './epics'; +import { onBeforeChange } from './utils/redux-first-router.js'; import servicesCreator from '../utils/services-creator'; -const createRouteProps = Observable.fromNodeCallback(match); - -// // createApp(settings: { -// location?: Location|String, // history?: History, -// syncHistoryWithStore?: ((history, store) => history) = (x) => x, -// initialState?: Object|Void, +// defaultState?: Object|Void, // serviceOptions?: Object, // middlewares?: Function[], -// sideReducers?: Object // enhancers?: Function[], // epics?: Function[], // }) => Observable // // Either location or history must be defined export default function createApp({ - location, history, - syncHistoryWithStore = (x) => x, - syncOptions = {}, - initialState, + defaultState, serviceOptions = {}, middlewares: sideMiddlewares = [], enhancers: sideEnhancers = [], - reducers: sideReducers = {}, epics: sideEpics = [], epicOptions: sideEpicOptions = {} }) { @@ -50,12 +43,25 @@ export default function createApp({ ...epics, ...sideEpics ); + + const { + reducer: routesReducer, + middleware: routesMiddleware, + enhancer: routesEnhancer + } = connectRoutes(history, routesMap, { onBeforeChange }); + + routesReducer.toString = () => 'location'; + const { reducer: panesReducer, middleware: panesMiddleware } = createPanesAspects(createPanesMap()); + const enhancer = compose( + addLangToRoutesEnhancer(routesMap), + routesEnhancer, applyMiddleware( + routesMiddleware, panesMiddleware, epicMiddleware, ...sideMiddlewares @@ -64,33 +70,31 @@ export default function createApp({ // on client side these are things like Redux DevTools ...sideEnhancers ); - const reducer = createReducer( - { - [panesReducer]: panesReducer, - ...sideReducers - }, + + const reducer = combineReducers( + appReducer, + panesReducer, + routesReducer ); // create composed store enhancer // use store enhancer function to enhance `createStore` function - // call enhanced createStore function with reducer and initialState + // call enhanced createStore function with reducer and defaultState // to create store - const store = createStore(reducer, initialState, enhancer); - // sync history client side with store. - // server side this is an identity function and history is undefined - history = syncHistoryWithStore(history, store, syncOptions); - const routes = createRoutes(store); - // createRouteProps({ - // redirect: LocationDescriptor, - // history: History, - // routes: Object - // }) => Observable - return createRouteProps({ routes, location, history }) - .map(([ redirect, props ]) => ({ - redirect, - props, - reducer, - store, - epic: epicMiddleware - })); + const store = createStore(reducer, defaultState, enhancer); + const location = selectLocationState(store.getState()); + + // ({ + // redirect, + // props, + // reducer, + // store, + // epic: epicMiddleware + // })); + return Observable.of({ + store, + epic: epicMiddleware, + location, + notFound: false + }); } diff --git a/common/app/create-reducer.js b/common/app/create-reducer.js deleted file mode 100644 index 869890cbcc..0000000000 --- a/common/app/create-reducer.js +++ /dev/null @@ -1,42 +0,0 @@ -import { combineReducers } from 'redux'; -import { reducer as formReducer } from 'redux-form'; - -import app from './redux'; -import entities from './entities'; -import map from './Map/redux'; -import nav from './Nav/redux'; -import routes from './routes/redux'; -import toasts from './Toasts/redux'; -// not ideal but should go away once we move to react-redux-form -import { projectNormalizer } from './routes/challenges/redux'; - -export default function createReducer(sideReducers) { - // reducers exported from features need to be factories - // this helps avoid cyclic requires messing up reducer creation - // We end up with exports from files being undefined as node tries - // to resolve cyclic dependencies. - // This prevents that by wrapping the `handleActions` call so that the ref - // to types imported from parent features are closures and can be resolved - // by node before we need them. - const reducerMap = [ - app, - entities, - map, - nav, - routes, - toasts - ] - .map(createReducer => createReducer()) - .reduce((arr, cur) => arr.concat(cur), []) - .reduce( - (reducerMap, reducer) => { - reducerMap[reducer] = reducer; - return reducerMap; - }, - { - form: formReducer.normalize({ ...projectNormalizer }), - ...sideReducers - } - ); - return combineReducers(reducerMap); -} diff --git a/common/app/create-routes.js b/common/app/create-routes.js deleted file mode 100644 index bae05c8e84..0000000000 --- a/common/app/create-routes.js +++ /dev/null @@ -1,9 +0,0 @@ -import App from './App.jsx'; -import createChildRoute from './routes'; - -export default function createRoutes(store) { - return { - components: App, - ...createChildRoute(store) - }; -} diff --git a/common/app/entities/index.js b/common/app/entities/index.js index e9e28c1a2c..c17146a35e 100644 --- a/common/app/entities/index.js +++ b/common/app/entities/index.js @@ -1,23 +1,22 @@ -import { createTypes } from 'redux-create-types'; -import { createAction, handleActions } from 'redux-actions'; +import { + composeReducers, + createAction, + createTypes, + handleActions +} from 'berkeleys-redux-utils'; + +import { types as app } from '../routes/Challenges/redux'; export const ns = 'entities'; export const getNS = state => state[ns]; export const entitiesSelector = getNS; export const types = createTypes([ - 'updateUserPoints', 'updateUserFlag', 'updateUserEmail', 'updateUserLang', - 'updateUserChallenge', 'updateUserCurrentChallenge' ], ns); -// updateUserPoints(username: String, points: Number) => Action -export const updateUserPoints = createAction( - types.updateUserPoints, - (username, points) => ({ username, points }) -); // updateUserFlag(username: String, flag: String) => Action export const updateUserFlag = createAction( types.updateUserFlag, @@ -34,21 +33,12 @@ export const updateUserLang = createAction( (username, lang) => ({ username, languageTag: lang }) ); -// updateUserChallenge( -// username: String, -// challengeInfo: Object -// ) => Action -export const updateUserChallenge = createAction( - types.updateUserChallenge, - (username, challengeInfo) => ({ username, challengeInfo }) -); - export const updateUserCurrentChallenge = createAction( types.updateUserCurrentChallenge ); -const initialState = { +const defaultState = { superBlock: {}, block: {}, challenge: {}, @@ -69,14 +59,33 @@ export function makeSuperBlockSelector(name) { }; } -export default function createReducer() { - const userReducer = handleActions( - { - [types.updateUserPoints]: (state, { payload: { username, points } }) => ({ +export const isChallengeLoaded = (state, { dashedName }) => + !!challengeMapSelector(state)[dashedName]; + +export default composeReducers( + ns, + function metaReducer(state = defaultState, action) { + if (action.meta && action.meta.entities) { + return { + ...state, + ...action.meta.entities + }; + } + return state; + }, + handleActions( + () => ({ + [ + app.submitChallenge.complete + ]: (state, { payload: { username, points, challengeInfo } }) => ({ ...state, [username]: { ...state[username], - points + points, + challengeMap: { + ...state[username].challengeMap, + [challengeInfo.id]: challengeInfo + } } }), [types.updateUserFlag]: (state, { payload: { username, flag } }) => ({ @@ -118,46 +127,8 @@ export default function createReducer() { ...state[username], currentChallengeId } - }), - [types.updateUserChallenge]: - ( - state, - { - payload: { username, challengeInfo } - } - ) => ({ - ...state, - [username]: { - ...state[username], - challengeMap: { - ...state[username].challengeMap, - [challengeInfo.id]: challengeInfo - } - } }) - }, - initialState.user - ); - - function metaReducer(state = initialState, action) { - if (action.meta && action.meta.entities) { - return { - ...state, - ...action.meta.entities - }; - } - return state; - } - - function entitiesReducer(state, action) { - const newState = metaReducer(state, action); - const user = userReducer(newState.user, action); - if (newState.user !== user) { - return { ...newState, user }; - } - return newState; - } - - entitiesReducer.toString = () => ns; - return entitiesReducer; -} + }), + defaultState + ) +); diff --git a/common/app/epics.js b/common/app/epics.js index 1b83fd1d2e..5c5372ed28 100644 --- a/common/app/epics.js +++ b/common/app/epics.js @@ -1,6 +1,6 @@ import { epics as app } from './redux'; -import { epics as challenge } from './routes/challenges/redux'; -import { epics as settings } from './routes/settings/redux'; +import { epics as challenge } from './routes/Challenges/redux'; +import { epics as settings } from './routes/Settings/redux'; import { epics as nav } from './Nav/redux'; import { epics as map } from './Map/redux'; import { epics as panes } from './Panes/redux'; diff --git a/common/app/files/index.js b/common/app/files/index.js new file mode 100644 index 0000000000..ddf8965b1e --- /dev/null +++ b/common/app/files/index.js @@ -0,0 +1,97 @@ +import { + combineActions, + createAction, + createTypes, + handleActions +} from 'berkeleys-redux-utils'; + +import { bonfire, html, js } from '../utils/challengeTypes.js'; +import { createPoly, setContent } from '../../utils/polyvinyl.js'; +import { arrayToString, buildSeed, getPreFile } from '../utils/classic-file.js'; +import { types as app } from '../redux'; +import { types as challenges } from '../routes/Challenges/redux'; + +const ns = 'files'; + +export const types = createTypes([ + 'updateFile', + 'updateFiles', + 'savedCodeFound' +], ns); + +export const updateFile = createAction(types.updateFile); +export const updateFiles = createAction(types.updateFiles); +export const savedCodeFound = createAction( + types.savedCodeFound, + (files, challenge) => ({ files, challenge }) +); + +export const filesSelector = state => state[ns]; + +export default handleActions( + () => ({ + [types.updateFile]: (state, { payload: { key, content }}) => ({ + ...state, + [key]: setContent(content, state[key]) + }), + [types.updateFiles]: (state, { payload: files }) => { + return files + .reduce((files, file) => { + files[file.key] = file; + return files; + }, { ...state }); + }, + [types.savedCodeFound]: (state, { payload: { files, challenge } }) => { + if (challenge.type === 'mod') { + // this may need to change to update head/tail + return challenge.files; + } + if ( + challenge.challengeType !== html && + challenge.challengeType !== js && + challenge.challengeType !== bonfire + ) { + return {}; + } + // classic challenge to modern format + const preFile = getPreFile(challenge); + return { + [preFile.key]: createPoly({ + ...files[preFile.key], + // make sure head/tail are always fresh + head: arrayToString(challenge.head), + tail: arrayToString(challenge.tail) + }) + }; + }, + [ + combineActions( + challenges.challengeUpdated, + app.fetchChallenge.complete + ) + ]: (state, { payload: { challenge } }) => { + if (challenge.type === 'mod') { + return challenge.files; + } + if ( + challenge.challengeType !== html && + challenge.challengeType !== js && + challenge.challengeType !== bonfire + ) { + return {}; + } + // classic challenge to modern format + const preFile = getPreFile(challenge); + return { + [preFile.key]: createPoly({ + ...preFile, + contents: buildSeed(challenge), + head: arrayToString(challenge.head), + tail: arrayToString(challenge.tail) + }) + }; + } + }), + {}, + ns +); diff --git a/common/app/index.js b/common/app/index.js index 1a3fead824..1aa4c9e6a6 100644 --- a/common/app/index.js +++ b/common/app/index.js @@ -1 +1,3 @@ -export default from './create-app.jsx'; +export { default as createApp } from './create-app.jsx'; +export { default as App } from './App.jsx'; +export { default as provideStore } from './provide-store.js'; diff --git a/common/app/provide-store.js b/common/app/provide-store.js index a569f64a5f..9584a5bdcb 100644 --- a/common/app/provide-store.js +++ b/common/app/provide-store.js @@ -1,11 +1,11 @@ /* eslint-disable react/display-name */ -import React from 'react'; +import { createElement } from 'react'; import { Provider } from 'react-redux'; -export default function provideStore(element, store) { - return React.createElement( +export default function provideStore(Component, store) { + return createElement( Provider, { store }, - element + createElement(Component) ); } diff --git a/common/app/reducer.js b/common/app/reducer.js new file mode 100644 index 0000000000..e8915b6e91 --- /dev/null +++ b/common/app/reducer.js @@ -0,0 +1,26 @@ +import { combineReducers } from 'berkeleys-redux-utils'; +import { reducer as formReducer } from 'redux-form'; + +import app from './redux'; +import entities from './entities'; +import map from './Map/redux'; +import nav from './Nav/redux'; +import routes from './routes/redux'; +import toasts from './Toasts/redux'; +import files from './files'; +// not ideal but should go away once we move to react-redux-form +import { projectNormalizer } from './routes/Challenges/redux'; + +const _formReducer = formReducer.normalize({ ...projectNormalizer }); +_formReducer.toString = () => 'form'; + +export default combineReducers( + app, + entities, + map, + nav, + routes, + toasts, + files, + _formReducer +); diff --git a/common/app/redux/fetch-challenges-epic.js b/common/app/redux/fetch-challenges-epic.js index ab8468530c..6c4dece21f 100644 --- a/common/app/redux/fetch-challenges-epic.js +++ b/common/app/redux/fetch-challenges-epic.js @@ -9,21 +9,23 @@ import { delayedRedirect, fetchChallengeCompleted, - fetchChallengesCompleted, - - langSelector + fetchChallengesCompleted } from './'; +import { isChallengeLoaded } from '../entities/index.js'; + import { shapeChallenges } from './utils'; +import { types as challenge } from '../routes/Challenges/redux'; +import { langSelector } from '../Router/redux'; const isDev = debug.enabled('fcc:*'); export function fetchChallengeEpic(actions, { getState }, { services }) { - return actions::ofType('' + types.fetchChallenge) - .flatMap(({ payload: { dashedName, block } }) => { - const lang = langSelector(getState()); + return actions::ofType(challenge.onRouteChallenges) + .filter(({ payload }) => !isChallengeLoaded(getState(), payload)) + .flatMapLatest(({ payload: params }) => { const options = { service: 'map', - params: { block, dashedName, lang } + params }; return services.readService$(options) .retry(3) @@ -52,11 +54,7 @@ export function fetchChallengesEpic( { getState }, { services } ) { - return actions::ofType( - // async type - '' + types.fetchChallenges, - types.appMounted - ) + return actions::ofType(types.appMounted) .flatMapLatest(() => { const lang = langSelector(getState()); const options = { diff --git a/common/app/redux/fetch-user-epic.js b/common/app/redux/fetch-user-epic.js index a409311e7a..32eb86429e 100644 --- a/common/app/redux/fetch-user-epic.js +++ b/common/app/redux/fetch-user-epic.js @@ -11,7 +11,7 @@ import { addThemeToBody } from './'; -export default function getUserEpic(actions, { getState }, { services }) { +export default function getUserEpic(actions, _, { services }) { return actions::ofType(types.fetchUser) .flatMap(() => { return services.readService$({ service: 'user' }) diff --git a/common/app/redux/index.js b/common/app/redux/index.js index e256de78ed..e802af869c 100644 --- a/common/app/redux/index.js +++ b/common/app/redux/index.js @@ -1,6 +1,11 @@ import { Observable } from 'rx'; -import { createTypes, createAsyncTypes } from 'redux-create-types'; -import { combineActions, createAction, handleActions } from 'redux-actions'; +import { + combineActions, + createAction, + createAsyncTypes, + createTypes, + handleActions +} from 'berkeleys-redux-utils'; import { createSelector } from 'reselect'; import noop from 'lodash/noop'; import identity from 'lodash/identity'; @@ -10,6 +15,7 @@ import fetchUserEpic from './fetch-user-epic.js'; import updateMyCurrentChallengeEpic from './update-my-challenge-epic.js'; import fetchChallengesEpic from './fetch-challenges-epic.js'; import navSizeEpic from './nav-size-epic.js'; +import { types as challenges } from '../routes/Challenges/redux'; import ns from '../ns.json'; @@ -21,14 +27,14 @@ export const epics = [ ]; export const types = createTypes([ + 'onRouteHome', + 'appMounted', 'analytics', 'updateTitle', - 'updateAppLang', createAsyncTypes('fetchChallenge'), createAsyncTypes('fetchChallenges'), - 'updateCurrentChallenge', 'fetchUser', 'addUser', @@ -80,6 +86,7 @@ export const createEventMetaCreator = ({ } }); +export const onRouteHome = createAction(types.onRouteHome); export const appMounted = createAction(types.appMounted); export const fetchChallenge = createAction( '' + types.fetchChallenge, @@ -96,9 +103,6 @@ export const fetchChallengesCompleted = createAction( (entities, result) => ({ entities, result }), entities => ({ entities }) ); -export const updateCurrentChallenge = createAction( - types.updateCurrentChallenge -); // updateTitle(title: String) => Action export const updateTitle = createAction(types.updateTitle); @@ -118,8 +122,6 @@ export const addUser = createAction( export const updateThisUser = createAction(types.updateThisUser); export const showSignIn = createAction(types.showSignIn); -export const updateAppLang = createAction(types.updateAppLang); - // used when server needs client to redirect export const delayedRedirect = createAction(types.delayedRedirect); @@ -156,7 +158,6 @@ const initialState = { title: 'Learn To Code | freeCodeCamp', isSignInAttempted: false, user: '', - lang: '', csrfToken: '', theme: 'default', // eventually this should be only in the user object @@ -165,7 +166,6 @@ const initialState = { }; export const getNS = state => state[ns]; -export const langSelector = state => getNS(state).lang; export const csrfSelector = state => getNS(state).csrfToken; export const themeSelector = state => getNS(state).theme; export const titleSelector = state => getNS(state).title; @@ -180,6 +180,8 @@ export const userSelector = createSelector( (username, userMap) => userMap[username] || {} ); +export const isSignedInSelector = state => !!userSelector(state).username; + export const challengeSelector = createSelector( currentChallengeSelector, state => entitiesSelector(state).challenge, @@ -222,58 +224,46 @@ export const firstChallengeSelector = createSelector( } ); -export default function createReducer() { - const reducer = handleActions( - { - [types.updateTitle]: (state, { payload = 'Learn To Code' }) => ({ - ...state, - title: payload + ' | freeCodeCamp' - }), +export default handleActions( + () => ({ + [types.updateTitle]: (state, { payload = 'Learn To Code' }) => ({ + ...state, + title: payload + ' | freeCodeCamp' + }), - [types.updateThisUser]: (state, { payload: user }) => ({ - ...state, - user - }), - [types.fetchChallenge.complete]: (state, { payload }) => ({ - ...state, - currentChallenge: payload.currentChallenge - }), - [combineActions( - types.fetchChallenge.complete, - types.fetchChallenges.complete - )]: (state, { payload }) => ({ - ...state, - superBlocks: payload.result.superBlocks - }), - [types.updateCurrentChallenge]: (state, { payload = '' }) => ({ - ...state, - currentChallenge: payload - }), - [types.updateAppLang]: (state, { payload = 'en' }) =>({ - ...state, - lang: payload - }), - [types.updateTheme]: (state, { payload = 'default' }) => ({ - ...state, - theme: payload - }), - [combineActions(types.showSignIn, types.updateThisUser)]: state => ({ - ...state, - isSignInAttempted: true - }), + [types.updateThisUser]: (state, { payload: user }) => ({ + ...state, + user + }), + [combineActions( + types.fetchChallenge.complete, + types.fetchChallenges.complete + )]: (state, { payload }) => ({ + ...state, + superBlocks: payload.result.superBlocks + }), + [challenges.onRouteChallenges]: (state, { payload: { dashedName } }) => ({ + ...state, + currentChallenge: dashedName + }), + [types.updateTheme]: (state, { payload = 'default' }) => ({ + ...state, + theme: payload + }), + [combineActions(types.showSignIn, types.updateThisUser)]: state => ({ + ...state, + isSignInAttempted: true + }), - [types.challengeSaved]: (state, { payload: { points = 0 } }) => ({ - ...state, - points - }), - [types.delayedRedirect]: (state, { payload }) => ({ - ...state, - delayedRedirect: payload - }) - }, - initialState - ); - - reducer.toString = () => ns; - return reducer; -} + [types.challengeSaved]: (state, { payload: { points = 0 } }) => ({ + ...state, + points + }), + [types.delayedRedirect]: (state, { payload }) => ({ + ...state, + delayedRedirect: payload + }) + }), + initialState, + ns +); diff --git a/common/app/redux/update-my-challenge-epic.js b/common/app/redux/update-my-challenge-epic.js index 26a74d9058..ad00a10331 100644 --- a/common/app/redux/update-my-challenge-epic.js +++ b/common/app/redux/update-my-challenge-epic.js @@ -12,12 +12,15 @@ import { } from './'; import { updateUserCurrentChallenge } from '../entities'; import { postJSON$ } from '../../utils/ajax-stream'; +import { types as challenges } from '../routes/Challenges/redux'; const log = debug('fcc:app:redux:up-my-challenge-epic'); export default function updateMyCurrentChallengeEpic(actions, { getState }) { - const updateChallenge = actions::ofType(types.updateCurrentChallenge) + const updateChallenge = actions::ofType(types.appMounted) + .flatMapLatest(() => actions::ofType(challenges.onRouteChallenges)) .map(() => { const state = getState(); + // username is never defined SSR const { username } = userSelector(state); const { id } = challengeSelector(state); const csrf = csrfSelector(state); diff --git a/common/app/redux/utils.js b/common/app/redux/utils.js index 10e152eea8..968ab97e60 100644 --- a/common/app/redux/utils.js +++ b/common/app/redux/utils.js @@ -10,7 +10,7 @@ export function filterComingSoonBetaChallenge( } export function filterComingSoonBetaFromEntities( - { challenge: challengeMap, block: blockMap, ...rest }, + { challenge: challengeMap, block: blockMap = {}, ...rest }, isDev = false ) { const filter = filterComingSoonBetaChallenge.bind(null, isDev); diff --git a/common/app/routes-map.js b/common/app/routes-map.js new file mode 100644 index 0000000000..ecbaac00f7 --- /dev/null +++ b/common/app/routes-map.js @@ -0,0 +1,19 @@ +import reduce from 'lodash/reduce'; +import { types } from './redux'; +import routes from './routes'; + +const base = '/:lang'; + +export default { + ...reduce(routes, (routes, route, type) => { + let newRoute; + if (typeof route === 'string') { + newRoute = base + route; + } else { + newRoute = { ...route, path: base + route.path }; + } + routes[type] = newRoute; + return routes; + }, {}), + [types.routeOnHome]: base +}; diff --git a/common/app/routes/challenges/Bug-Modal.jsx b/common/app/routes/Challenges/Bug-Modal.jsx similarity index 97% rename from common/app/routes/challenges/Bug-Modal.jsx rename to common/app/routes/Challenges/Bug-Modal.jsx index 1cf05f2634..7366957d9d 100644 --- a/common/app/routes/challenges/Bug-Modal.jsx +++ b/common/app/routes/Challenges/Bug-Modal.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { Button, Modal } from 'react-bootstrap'; import PureComponent from 'react-pure-render/component'; diff --git a/common/app/routes/challenges/Challenge-Description.jsx b/common/app/routes/Challenges/Challenge-Description.jsx similarity index 87% rename from common/app/routes/challenges/Challenge-Description.jsx rename to common/app/routes/Challenges/Challenge-Description.jsx index 566684a0c0..0aedaa13d3 100644 --- a/common/app/routes/challenges/Challenge-Description.jsx +++ b/common/app/routes/Challenges/Challenge-Description.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import { Col, Row } from 'react-bootstrap'; import ns from './ns.json'; diff --git a/common/app/routes/challenges/Challenge-Title.jsx b/common/app/routes/Challenges/Challenge-Title.jsx similarity index 90% rename from common/app/routes/challenges/Challenge-Title.jsx rename to common/app/routes/Challenges/Challenge-Title.jsx index 8924b71f85..a2c98f81d0 100644 --- a/common/app/routes/challenges/Challenge-Title.jsx +++ b/common/app/routes/Challenges/Challenge-Title.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import ns from './ns.json'; diff --git a/common/app/routes/challenges/Code-Mirror-Skeleton.jsx b/common/app/routes/Challenges/Code-Mirror-Skeleton.jsx similarity index 96% rename from common/app/routes/challenges/Code-Mirror-Skeleton.jsx rename to common/app/routes/Challenges/Code-Mirror-Skeleton.jsx index b694652ba4..0b07b8a32c 100644 --- a/common/app/routes/challenges/Code-Mirror-Skeleton.jsx +++ b/common/app/routes/Challenges/Code-Mirror-Skeleton.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import PureComponent from 'react-pure-render/component'; import { Grid, Col, Row } from 'react-bootstrap'; diff --git a/common/app/routes/challenges/Completion-Modal.jsx b/common/app/routes/Challenges/Completion-Modal.jsx similarity index 96% rename from common/app/routes/challenges/Completion-Modal.jsx rename to common/app/routes/Challenges/Completion-Modal.jsx index 4ea37e7080..27a5cab7e2 100644 --- a/common/app/routes/challenges/Completion-Modal.jsx +++ b/common/app/routes/Challenges/Completion-Modal.jsx @@ -1,5 +1,6 @@ import noop from 'lodash/noop'; -import React, { PureComponent, PropTypes } from 'react'; +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { createSelector } from 'reselect'; import { Button, Modal } from 'react-bootstrap'; diff --git a/common/app/routes/challenges/Output.jsx b/common/app/routes/Challenges/Output.jsx similarity index 91% rename from common/app/routes/challenges/Output.jsx rename to common/app/routes/Challenges/Output.jsx index eb27d3c860..93b2a680db 100644 --- a/common/app/routes/challenges/Output.jsx +++ b/common/app/routes/Challenges/Output.jsx @@ -1,4 +1,5 @@ -import React, { PureComponent, PropTypes } from 'react'; +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; import NoSSR from 'react-no-ssr'; import Codemirror from 'react-codemirror'; diff --git a/common/app/routes/Challenges/Show.jsx b/common/app/routes/Challenges/Show.jsx new file mode 100644 index 0000000000..b59dd7dce1 --- /dev/null +++ b/common/app/routes/Challenges/Show.jsx @@ -0,0 +1,113 @@ +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import { createSelector } from 'reselect'; + +import { challengeMetaSelector } from './redux'; + +import CompletionModal from './Completion-Modal.jsx'; +import Classic from './views/classic'; +import Step from './views/step'; +import Project from './views/project'; +import BackEnd from './views/backend'; +import Quiz from './views/quiz'; + +import { + fetchChallenge, + + challengeSelector +} from '../../redux'; +import { makeToast } from '../../Toasts/redux'; +import { paramsSelector } from '../../Router/redux'; + +const views = { + backend: BackEnd, + classic: Classic, + project: Project, + simple: Project, + step: Step, + quiz: Quiz +}; + +const mapDispatchToProps = { + fetchChallenge, + makeToast +}; + +const mapStateToProps = createSelector( + challengeSelector, + challengeMetaSelector, + paramsSelector, + ( + { dashedName, isTranslated }, + { viewType }, + params, + ) => ({ + challenge: dashedName, + isTranslated, + params, + viewType + }) +); + +const link = 'http://forum.freecodecamp.org/t/' + + 'guidelines-for-translating-free-code-camp' + + '-to-any-language/19111'; +const helpUsTranslate = Help Us; +const propTypes = { + isTranslated: PropTypes.bool, + makeToast: PropTypes.func.isRequired, + params: PropTypes.shape({ + block: PropTypes.string, + dashedName: PropTypes.string, + lang: PropTypes.string.isRequired + }), + viewType: PropTypes.string +}; + +export class Show extends PureComponent { + + isNotTranslated({ isTranslated, params: { lang } }) { + return lang !== 'en' && !isTranslated; + } + + makeTranslateToast() { + this.props.makeToast({ + message: 'We haven\'t translated this challenge yet.', + action: helpUsTranslate, + timeout: 15000 + }); + } + + componentDidMount() { + if (this.isNotTranslated(this.props)) { + this.makeTranslateToast(); + } + } + + componentWillReceiveProps(nextProps) { + const { params: { dashedName } } = nextProps; + if ( + this.props.params.dashedName !== dashedName && + this.isNotTranslated(nextProps) + ) { + this.makeTranslateToast(); + } + } + + render() { + const { viewType } = this.props; + const View = views[viewType] || Classic; + return ( +
+ + +
+ ); + } +} + +Show.displayName = 'Show(ChallengeView)'; +Show.propTypes = propTypes; + +export default connect(mapStateToProps, mapDispatchToProps)(Show); diff --git a/common/app/routes/challenges/Solution-Input.jsx b/common/app/routes/Challenges/Solution-Input.jsx similarity index 93% rename from common/app/routes/challenges/Solution-Input.jsx rename to common/app/routes/Challenges/Solution-Input.jsx index bb242c254f..f5a4601f19 100644 --- a/common/app/routes/challenges/Solution-Input.jsx +++ b/common/app/routes/Challenges/Solution-Input.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import { HelpBlock, FormGroup, FormControl } from 'react-bootstrap'; import { getValidationState, DOMOnlyProps } from '../../utils/form'; diff --git a/common/app/routes/challenges/Test-Suite.jsx b/common/app/routes/Challenges/Test-Suite.jsx similarity index 95% rename from common/app/routes/challenges/Test-Suite.jsx rename to common/app/routes/Challenges/Test-Suite.jsx index da7ad7e2c6..7f713963d1 100644 --- a/common/app/routes/challenges/Test-Suite.jsx +++ b/common/app/routes/Challenges/Test-Suite.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes, PureComponent } from 'react'; +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; import classnames from 'classnames'; import { Col, Row } from 'react-bootstrap'; diff --git a/common/app/routes/challenges/challenges.less b/common/app/routes/Challenges/challenges.less similarity index 100% rename from common/app/routes/challenges/challenges.less rename to common/app/routes/Challenges/challenges.less diff --git a/common/app/routes/Challenges/index.js b/common/app/routes/Challenges/index.js new file mode 100644 index 0000000000..debe8352ed --- /dev/null +++ b/common/app/routes/Challenges/index.js @@ -0,0 +1,33 @@ +import { redirect } from 'redux-first-router'; + +import { types } from './redux'; +import { panesMap as backendPanesMap } from './views/backend'; +import { panesMap as classicPanesMap } from './views/classic'; +import { panesMap as stepPanesMap } from './views/step'; +import { panesMap as projectPanesMap } from './views/project'; +import { panesMap as quizPanesMap } from './views/quiz'; + +export const routes = { + [types.onRouteChallengeRoot]: { + path: '/challenges', + thunk: (dispatch) => + dispatch(redirect({ type: types.onRouteCurrentChallenge })) + }, + [types.onRouteChallenges]: '/challenges/:block/:dashedName', + [types.onRouteCurrentChallenge]: '/challenges/current-challenge' +}; + +export function createPanesMap() { + return { + // the route to use this panes map on + [types.onRouteChallenges]: { + [backendPanesMap]: backendPanesMap, + [classicPanesMap]: classicPanesMap, + [stepPanesMap]: stepPanesMap, + [projectPanesMap]: projectPanesMap, + [quizPanesMap]: quizPanesMap + } + }; +} + +export { default } from './Show.jsx'; diff --git a/common/app/routes/challenges/ns.json b/common/app/routes/Challenges/ns.json similarity index 100% rename from common/app/routes/challenges/ns.json rename to common/app/routes/Challenges/ns.json diff --git a/common/app/routes/challenges/redux/bug-epic.js b/common/app/routes/Challenges/redux/bug-epic.js similarity index 97% rename from common/app/routes/challenges/redux/bug-epic.js rename to common/app/routes/Challenges/redux/bug-epic.js index aac21ec207..b75715605f 100644 --- a/common/app/routes/challenges/redux/bug-epic.js +++ b/common/app/routes/Challenges/redux/bug-epic.js @@ -1,11 +1,10 @@ import { ofType } from 'redux-epic'; import { types, - closeBugModal, - - filesSelector + closeBugModal } from '../redux'; +import { filesSelector } from '../../../files'; import { currentChallengeSelector } from '../../../redux'; function filesToMarkdown(files = {}) { diff --git a/common/app/routes/challenges/redux/challenge-epic.js b/common/app/routes/Challenges/redux/challenge-epic.js similarity index 67% rename from common/app/routes/challenges/redux/challenge-epic.js rename to common/app/routes/Challenges/redux/challenge-epic.js index 3f69fe0bce..57c45d1aad 100644 --- a/common/app/routes/challenges/redux/challenge-epic.js +++ b/common/app/routes/Challenges/redux/challenge-epic.js @@ -1,13 +1,14 @@ import debug from 'debug'; import { Observable } from 'rx'; import { combineEpics, ofType } from 'redux-epic'; -import { push } from 'react-router-redux'; import { types, - updateMain, - challengeUpdated + challengeUpdated, + onRouteChallenges, + onRouteCurrentChallenge, + updateMain } from './'; import { getNS as entitiesSelector } from '../../../entities'; import { @@ -16,40 +17,42 @@ import { getFirstChallengeOfNextSuperBlock } from '../utils'; import { - types as app, - createErrorObservable, - updateCurrentChallenge, - currentChallengeSelector, challengeSelector, superBlocksSelector } from '../../../redux'; +import { langSelector } from '../../../Router/redux'; import { makeToast } from '../../../Toasts/redux'; const isDev = debug.enabled('fcc:*'); +// When we change challenge, update the current challenge +// UI data. export function challengeUpdatedEpic(actions, { getState }) { - return actions::ofType(app.updateCurrentChallenge) - .flatMap(() => { - const challenge = challengeSelector(getState()); - return Observable.of( - challengeUpdated(challenge), - push(`/challenges/${challenge.block}/${challenge.dashedName}`) - ); - }); + return actions::ofType(types.onRouteChallenges) + // prevent subsequent onRouteChallenges to cause UI to refresh + .distinctUntilChanged(({ payload: { dashedName }}) => dashedName) + .map(() => challengeSelector(getState())) + // if the challenge isn't loaded in the current state, + // this will be an empty object + // We wait instead for the fetchChallenge.complete to complete the UI state + .filter(({ dashedName }) => !!dashedName) + .flatMap(challenge => + // send the challenge to update UI and update main iframe with inital + // challenge + Observable.of(challengeUpdated(challenge), updateMain()) + ); } // used to reset users code on request export function resetChallengeEpic(actions, { getState }) { - return actions::ofType(types.resetChallenge) - .flatMap(() => { - const currentChallenge = currentChallengeSelector(getState()); - return Observable.of( - updateCurrentChallenge(currentChallenge), + return actions::ofType(types.clickOnReset) + .flatMap(() => + Observable.of( + challengeUpdated(challengeSelector(getState())), updateMain() - ); - }); + )); } export function nextChallengeEpic(actions, { getState }) { @@ -64,6 +67,7 @@ export function nextChallengeEpic(actions, { getState }) { const superBlocks = superBlocksSelector(state); const challenge = currentChallengeSelector(state); const entities = entitiesSelector(state); + const lang = langSelector(state); nextChallenge = getNextChallenge(challenge, entities, { isDev }); // block completed. if (!nextChallenge) { @@ -107,11 +111,15 @@ export function nextChallengeEpic(actions, { getState }) { 'that have not been passed yet. ', timeout: 15000 }), - push('/map') + onRouteCurrentChallenge() ); } return Observable.of( - updateCurrentChallenge(nextChallenge.dashedName), + // normally we wouldn't need to add the lang as + // addLangToRoutesEnhancer should add langs for us, but the way + // enhancers/middlewares and RFR orders things this action will not + // see addLangToRoutesEnhancer and cause RFR to render NotFound + onRouteChallenges({ lang, ...nextChallenge }), makeToast({ message: 'Your next challenge has arrived.' }) ); } catch (err) { diff --git a/common/app/routes/challenges/redux/completion-epic.js b/common/app/routes/Challenges/redux/completion-epic.js similarity index 79% rename from common/app/routes/challenges/redux/completion-epic.js rename to common/app/routes/Challenges/redux/completion-epic.js index 8432a1a8b3..2d64fce0ba 100644 --- a/common/app/routes/challenges/redux/completion-epic.js +++ b/common/app/routes/Challenges/redux/completion-epic.js @@ -2,48 +2,45 @@ import { Observable } from 'rx'; import { ofType } from 'redux-epic'; import { - types, - - moveToNextChallenge, - clearSavedCode, - challengeMetaSelector, - filesSelector, - testsSelector + moveToNextChallenge, + submitChallengeComplete, + testsSelector, + types } from './'; import { - createErrorObservable, - challengeSelector, + createErrorObservable, csrfSelector, userSelector } from '../../../redux'; -import { - updateUserPoints, - updateUserChallenge -} from '../../../entities'; +import { filesSelector } from '../../../files'; import { backEndProject } from '../../../utils/challengeTypes.js'; import { makeToast } from '../../../Toasts/redux'; import { postJSON$ } from '../../../../utils/ajax-stream.js'; function postChallenge(url, username, _csrf, challengeInfo) { - const body = { ...challengeInfo, _csrf }; - const saveChallenge = postJSON$(url, body) - .retry(3) - .flatMap(({ points, lastUpdated, completedDate }) => { - return Observable.of( - updateUserPoints(username, points), - updateUserChallenge( - username, - { ...challengeInfo, lastUpdated, completedDate } - ), - clearSavedCode() - ); - }) - .catch(createErrorObservable); - const challengeCompleted = Observable.of(moveToNextChallenge()); - return Observable.merge(saveChallenge, challengeCompleted); + return Observable.if( + () => !!username, + Observable.defer(() => { + const body = { ...challengeInfo, _csrf }; + const saveChallenge = postJSON$(url, body) + .retry(3) + .map(({ points, lastUpdated, completedDate }) => + submitChallengeComplete( + username, + points, + { ...challengeInfo, lastUpdated, completedDate } + ) + ) + .catch(createErrorObservable); + const challengeCompleted = Observable.of(moveToNextChallenge()); + return Observable.merge(saveChallenge, challengeCompleted) + .startWith({ type: types.submitChallenge.start }); + }), + Observable.of(moveToNextChallenge()) + ); } function submitModern(type, state) { @@ -53,7 +50,7 @@ function submitModern(type, state) { return Observable.empty(); } - if (type === types.submitChallenge) { + if (type === types.submitChallenge.toString()) { const { id } = challengeSelector(state); const files = filesSelector(state); const { username } = userSelector(state); @@ -145,7 +142,7 @@ const submitters = { }; export default function completionEpic(actions, { getState }) { - return actions::ofType(types.checkChallenge, types.submitChallenge) + return actions::ofType(types.checkChallenge, types.submitChallenge.toString()) .flatMap(({ type, payload }) => { const state = getState(); const { submitType } = challengeMetaSelector(state); diff --git a/common/app/routes/challenges/redux/editor-epic.js b/common/app/routes/Challenges/redux/editor-epic.js similarity index 87% rename from common/app/routes/challenges/redux/editor-epic.js rename to common/app/routes/Challenges/redux/editor-epic.js index 33eda718cc..c5967fe981 100644 --- a/common/app/routes/challenges/redux/editor-epic.js +++ b/common/app/routes/Challenges/redux/editor-epic.js @@ -2,11 +2,11 @@ import { ofType } from 'redux-epic'; import { types, - updateFile, - keySelector } from './'; +import { updateFile } from '../../../files'; + export default function editorEpic(actions, { getState }) { return actions::ofType(types.classicEditorUpdated) .pluck('payload') diff --git a/common/app/routes/challenges/redux/index.js b/common/app/routes/Challenges/redux/index.js similarity index 58% rename from common/app/routes/challenges/redux/index.js rename to common/app/routes/Challenges/redux/index.js index 5feb5d5ca1..68265b6f64 100644 --- a/common/app/routes/challenges/redux/index.js +++ b/common/app/routes/Challenges/redux/index.js @@ -1,5 +1,11 @@ -import { createTypes } from 'redux-create-types'; -import { createAction, combineActions, handleActions } from 'redux-actions'; +import { + combineActions, + combineReducers, + createAction, + createAsyncTypes, + createTypes, + handleActions +} from 'berkeleys-redux-utils'; import { createSelector } from 'reselect'; import noop from 'lodash/noop'; @@ -10,11 +16,7 @@ import editorEpic from './editor-epic.js'; import ns from '../ns.json'; import { - arrayToString, - buildSeed, createTests, - getFileKey, - getPreFile, loggerToStr, submitTypes, viewTypes @@ -23,12 +25,12 @@ import { types as app, challengeSelector } from '../../../redux'; -import { bonfire, html, js } from '../../../utils/challengeTypes'; -import blockNameify from '../../../utils/blockNameify'; -import { createPoly, setContent } from '../../../../utils/polyvinyl'; -import createStepReducer, { epics as stepEpics } from '../views/step/redux'; -import createQuizReducer from '../views/quiz/redux'; -import createProjectReducer from '../views/project/redux'; +import { html } from '../../../utils/challengeTypes.js'; +import blockNameify from '../../../utils/blockNameify.js'; +import { getFileKey } from '../../../utils/classic-file.js'; +import stepReducer, { epics as stepEpics } from '../views/step/redux'; +import quizReducer from '../views/quiz/redux'; +import projectReducer from '../views/project/redux'; // this is not great but is ok until we move to a different form type export projectNormalizer from '../views/project/redux'; @@ -42,21 +44,20 @@ export const epics = [ ]; export const types = createTypes([ + 'onRouteChallengeRoot', + 'onRouteChallenges', + 'onRouteCurrentChallenge', // challenges // |- classic 'classicEditorUpdated', 'challengeUpdated', - 'resetChallenge', + 'clickOnReset', 'updateHint', 'lockUntrustedCode', 'unlockUntrustedCode', 'closeChallengeModal', 'updateSuccessMessage', - // files - 'updateFile', - 'updateFiles', - // rechallenge 'executeChallenge', 'updateMain', @@ -67,15 +68,9 @@ export const types = createTypes([ 'initOutput', 'updateTests', 'checkChallenge', - 'submitChallenge', + createAsyncTypes('submitChallenge'), 'moveToNextChallenge', - // code storage - 'saveCode', - 'loadCode', - 'savedCodeFound', - 'clearSavedCode', - // bug 'openBugModal', 'closeBugModal', @@ -91,6 +86,11 @@ export const types = createTypes([ 'toggleStep' ], ns); +// routes +export const onRouteChallenges = createAction(types.onRouteChallenges); +export const onRouteCurrentChallenge = + createAction(types.onRouteCurrentChallenge); + // classic export const classicEditorUpdated = createAction(types.classicEditorUpdated); // challenges @@ -106,10 +106,7 @@ export const challengeUpdated = createAction( types.challengeUpdated, challenge => ({ challenge }) ); -export const resetChallenge = createAction(types.resetChallenge); -// files -export const updateFile = createAction(types.updateFile); -export const updateFiles = createAction(types.updateFiles); +export const clickOnReset = createAction(types.clickOnReset); // rechallenge export const executeChallenge = createAction( @@ -130,16 +127,12 @@ export const updateOutput = createAction(types.updateOutput, loggerToStr); export const checkChallenge = createAction(types.checkChallenge); export const submitChallenge = createAction(types.submitChallenge); -export const moveToNextChallenge = createAction(types.moveToNextChallenge); - -// code storage -export const saveCode = createAction(types.saveCode); -export const loadCode = createAction(types.loadCode); -export const savedCodeFound = createAction( - types.savedCodeFound, - (files, challenge) => ({ files, challenge }) +export const submitChallengeComplete = createAction( + types.submitChallenge.complete, + (username, points, challengeInfo) => ({ username, points, challengeInfo }) ); -export const clearSavedCode = createAction(types.clearSavedCode); + +export const moveToNextChallenge = createAction(types.moveToNextChallenge); // bug export const openBugModal = createAction(types.openBugModal); @@ -151,9 +144,7 @@ const initialUiState = { output: null, isChallengeModalOpen: false, isBugOpen: false, - successMessage: 'Happy Coding!', - hintIndex: 0, - numOfHints: 0 + successMessage: 'Happy Coding!' }; const initialState = { @@ -163,7 +154,6 @@ const initialState = { helpChatRoom: 'Help', // old code storage key legacyKey: '', - files: {}, // map superBlocks: [], // misc @@ -172,7 +162,6 @@ const initialState = { export const getNS = state => state[ns]; export const keySelector = state => getNS(state).key; -export const filesSelector = state => getNS(state).files; export const testsSelector = state => getNS(state).tests; export const outputSelector = state => getNS(state).output; @@ -186,7 +175,8 @@ export const challengeModalSelector = export const bugModalSelector = state => getNS(state).isBugOpen; export const challengeMetaSelector = createSelector( - challengeSelector, + // use closure to get around circular deps + (...args) => challengeSelector(...args), challenge => { if (!challenge.id) { return {}; @@ -214,15 +204,15 @@ export const challengeMetaSelector = createSelector( } ); -export default function createReducers() { - const setChallengeType = combineActions( - types.challengeUpdated, - app.fetchChallenge.complete - ); - - const mainReducer = handleActions( - { - [setChallengeType]: (state, { payload: { challenge } }) => { +export default combineReducers( + handleActions( + () => ({ + [ + combineActions( + types.challengeUpdated, + app.fetchChallenge.complete + ) + ]: (state, { payload: { challenge } }) => { return { ...state, ...initialUiState, @@ -230,10 +220,7 @@ export default function createReducers() { challenge: challenge.dashedName, key: getFileKey(challenge), tests: createTests(challenge), - helpChatRoom: challenge.helpRoom || 'Help', - numOfHints: Array.isArray(challenge.hints) ? - challenge.hints.length : - 0 + helpChatRoom: challenge.helpRoom || 'Help' }; }, [types.updateTests]: (state, { payload: tests }) => ({ @@ -252,12 +239,6 @@ export default function createReducers() { ...state, successMessage: payload }), - [types.updateHint]: state => ({ - ...state, - hintIndex: state.hintIndex + 1 >= state.numOfHints ? - 0 : - state.hintIndex + 1 - }), [types.lockUntrustedCode]: state => ({ ...state, isCodeLocked: true @@ -283,86 +264,11 @@ export default function createReducers() { [types.openBugModal]: state => ({ ...state, isBugOpen: true }), [types.closeBugModal]: state => ({ ...state, isBugOpen: false }) - }, - initialState - ); - - const filesReducer = handleActions( - { - [types.updateFile]: (state, { payload: { key, content }}) => ({ - ...state, - [key]: setContent(content, state[key]) - }), - [types.updateFiles]: (state, { payload: files }) => { - return files - .reduce((files, file) => { - files[file.key] = file; - return files; - }, { ...state }); - }, - [types.savedCodeFound]: (state, { payload: { files, challenge } }) => { - if (challenge.type === 'mod') { - // this may need to change to update head/tail - return challenge.files; - } - if ( - challenge.challengeType !== html && - challenge.challengeType !== js && - challenge.challengeType !== bonfire - ) { - return {}; - } - // classic challenge to modern format - const preFile = getPreFile(challenge); - return { - [preFile.key]: createPoly({ - ...files[preFile.key], - // make sure head/tail are always fresh - head: arrayToString(challenge.head), - tail: arrayToString(challenge.tail) - }) - }; - }, - [setChallengeType]: (state, { payload: { challenge } }) => { - if (challenge.type === 'mod') { - return challenge.files; - } - if ( - challenge.challengeType !== html && - challenge.challengeType !== js && - challenge.challengeType !== bonfire - ) { - return {}; - } - // classic challenge to modern format - const preFile = getPreFile(challenge); - return { - [preFile.key]: createPoly({ - ...preFile, - contents: buildSeed(challenge), - head: arrayToString(challenge.head), - tail: arrayToString(challenge.tail) - }) - }; - } - }, - {} - ); - - function reducer(state, action) { - const newState = mainReducer(state, action); - const files = filesReducer(state && state.files || {}, action); - if (newState.files !== files) { - return { ...newState, files }; - } - return newState; - } - - reducer.toString = () => ns; - return [ - reducer, - ...createStepReducer(), - ...createProjectReducer(), - ...createQuizReducer() - ]; -} + }), + initialState, + ns + ), + stepReducer, + quizReducer, + projectReducer +); diff --git a/common/app/routes/challenges/utils.js b/common/app/routes/Challenges/utils.js similarity index 89% rename from common/app/routes/challenges/utils.js rename to common/app/routes/Challenges/utils.js index 45ead3e449..5f04d16630 100644 --- a/common/app/routes/challenges/utils.js +++ b/common/app/routes/Challenges/utils.js @@ -1,6 +1,4 @@ -import flow from 'lodash/flow'; import * as challengeTypes from '../../utils/challengeTypes'; -import { decodeScriptTags } from '../../../utils/encode-decode'; // determine the component to view for each challenge export const viewTypes = { @@ -43,36 +41,6 @@ export const submitTypes = { // has html that should be rendered export const descriptionRegex = /\ '' + seed + line + '\n', '\n'); -} - -export function buildSeed({ challengeSeed = [] } = {}) { - return flow( - arrayToString, - decodeScriptTags - )(challengeSeed); -} - -const pathsMap = { - [ challengeTypes.html ]: 'html', - [ challengeTypes.js ]: 'js', - [ challengeTypes.bonfire ]: 'js' -}; - -export function getPreFile({ challengeType }) { - return { - name: 'index', - ext: pathsMap[challengeType] || 'html', - key: getFileKey({ challengeType }) - }; -} - -export function getFileKey({ challengeType }) { - return 'index' + (pathsMap[challengeType] || 'html'); -} - export function createTests({ tests = [] }) { return tests .map(test => { diff --git a/common/app/routes/challenges/utils.test.js b/common/app/routes/Challenges/utils.test.js similarity index 100% rename from common/app/routes/challenges/utils.test.js rename to common/app/routes/Challenges/utils.test.js diff --git a/common/app/routes/challenges/views/backend/Back-End.jsx b/common/app/routes/Challenges/views/backend/Back-End.jsx similarity index 98% rename from common/app/routes/challenges/views/backend/Back-End.jsx rename to common/app/routes/Challenges/views/backend/Back-End.jsx index 686f0a8948..47338139a9 100644 --- a/common/app/routes/challenges/views/backend/Back-End.jsx +++ b/common/app/routes/Challenges/views/backend/Back-End.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes, PureComponent } from 'react'; +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; import { createSelector } from 'reselect'; import { reduxForm } from 'redux-form'; import { diff --git a/common/app/routes/challenges/views/backend/Show.jsx b/common/app/routes/Challenges/views/backend/Show.jsx similarity index 77% rename from common/app/routes/challenges/views/backend/Show.jsx rename to common/app/routes/Challenges/views/backend/Show.jsx index 477083c7e1..47a8dbc336 100644 --- a/common/app/routes/challenges/views/backend/Show.jsx +++ b/common/app/routes/Challenges/views/backend/Show.jsx @@ -3,15 +3,19 @@ import React from 'react'; import BackEnd from './Back-End.jsx'; import { types } from '../../redux'; import Panes from '../../../../Panes'; +import { createPaneMap } from '../../../../Panes/redux'; import _Map from '../../../../Map'; import ChildContainer from '../../../../Child-Container.jsx'; const propTypes = {}; -export const panesMap = { - [types.toggleMap]: 'Map', - [types.toggleMain]: 'Main' -}; +export const panesMap = createPaneMap( + 'backend', + () => ({ + [types.toggleMap]: 'Map', + [types.toggleMain]: 'Main' + }) +); const nameToComponentDef = { Map: { diff --git a/common/app/routes/challenges/views/backend/index.js b/common/app/routes/Challenges/views/backend/index.js similarity index 100% rename from common/app/routes/challenges/views/backend/index.js rename to common/app/routes/Challenges/views/backend/index.js diff --git a/common/app/routes/challenges/views/classic/Editor.jsx b/common/app/routes/Challenges/views/classic/Editor.jsx similarity index 95% rename from common/app/routes/challenges/views/classic/Editor.jsx rename to common/app/routes/Challenges/views/classic/Editor.jsx index 5d33a8c5d6..94cbe65b74 100644 --- a/common/app/routes/challenges/views/classic/Editor.jsx +++ b/common/app/routes/Challenges/views/classic/Editor.jsx @@ -1,4 +1,5 @@ -import React, { PureComponent, PropTypes } from 'react'; +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { createSelector } from 'reselect'; @@ -12,10 +13,11 @@ import { executeChallenge, classicEditorUpdated, challengeMetaSelector, - filesSelector, keySelector } from '../../redux'; +import { filesSelector } from '../../../../files'; + const envProps = typeof window !== 'undefined' ? Object.keys(window) : []; const options = { lint: { diff --git a/common/app/routes/challenges/views/classic/Preview.jsx b/common/app/routes/Challenges/views/classic/Preview.jsx similarity index 100% rename from common/app/routes/challenges/views/classic/Preview.jsx rename to common/app/routes/Challenges/views/classic/Preview.jsx diff --git a/common/app/routes/challenges/views/classic/Show.jsx b/common/app/routes/Challenges/views/classic/Show.jsx similarity index 63% rename from common/app/routes/challenges/views/classic/Show.jsx rename to common/app/routes/Challenges/views/classic/Show.jsx index 09b9bfc409..cfcb99b203 100644 --- a/common/app/routes/challenges/views/classic/Show.jsx +++ b/common/app/routes/Challenges/views/classic/Show.jsx @@ -3,19 +3,26 @@ import React from 'react'; import SidePanel from './Side-Panel.jsx'; import Editor from './Editor.jsx'; import Preview from './Preview.jsx'; -import { types } from '../../redux'; +import { types, challengeMetaSelector } from '../../redux'; import Panes from '../../../../Panes'; +import { createPaneMap } from '../../../../Panes/redux'; import _Map from '../../../../Map'; import ChildContainer from '../../../../Child-Container.jsx'; const propTypes = {}; -export const panesMap = { - [types.toggleMap]: 'Map', - [types.toggleSidePanel]: 'Side Panel', - [types.toggleClassicEditor]: 'Editor', - [types.togglePreview]: 'Preview' -}; +export const panesMap = createPaneMap( + 'classic', + () => ({ + [types.toggleMap]: 'Map', + [types.toggleSidePanel]: 'Side Panel', + [types.toggleClassicEditor]: 'Editor', + [types.togglePreview]: { + name: 'Preview', + filter: state => !!challengeMetaSelector(state).showPreview + } + }) +); const nameToComponent = { Map: { diff --git a/common/app/routes/challenges/views/classic/Side-Panel.jsx b/common/app/routes/Challenges/views/classic/Side-Panel.jsx similarity index 97% rename from common/app/routes/challenges/views/classic/Side-Panel.jsx rename to common/app/routes/Challenges/views/classic/Side-Panel.jsx index 511623944b..da57345bb9 100644 --- a/common/app/routes/challenges/views/classic/Side-Panel.jsx +++ b/common/app/routes/Challenges/views/classic/Side-Panel.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import ReactDom from 'react-dom'; import { createSelector } from 'reselect'; import { connect } from 'react-redux'; @@ -46,10 +47,7 @@ const mapStateToProps = createSelector( codeLockedSelector, chatRoomSelector, ( - { - description, - hints = [] - }, + { description }, { title }, tests, output, @@ -61,7 +59,6 @@ const mapStateToProps = createSelector( description, tests, output, - hint: hints[hintIndex], isCodeLocked, helpChatRoom }) diff --git a/common/app/routes/challenges/views/classic/Tool-Panel.jsx b/common/app/routes/Challenges/views/classic/Tool-Panel.jsx similarity index 97% rename from common/app/routes/challenges/views/classic/Tool-Panel.jsx rename to common/app/routes/Challenges/views/classic/Tool-Panel.jsx index 6b48bf580e..9aa5b754bc 100644 --- a/common/app/routes/challenges/views/classic/Tool-Panel.jsx +++ b/common/app/routes/Challenges/views/classic/Tool-Panel.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import { Button, ButtonGroup, Tooltip, OverlayTrigger } from 'react-bootstrap'; import PureComponent from 'react-pure-render/component'; @@ -39,7 +40,7 @@ export default class ToolPanel extends PureComponent { this.props.makeToast({ message: 'This will restore your code editor to its original state.', action: 'clear my code', - actionCreator: 'resetChallenge', + actionCreator: 'clickOnReset', timeout: 4000 }); } diff --git a/common/app/routes/challenges/views/classic/classic.less b/common/app/routes/Challenges/views/classic/classic.less similarity index 100% rename from common/app/routes/challenges/views/classic/classic.less rename to common/app/routes/Challenges/views/classic/classic.less diff --git a/common/app/routes/challenges/views/classic/index.js b/common/app/routes/Challenges/views/classic/index.js similarity index 100% rename from common/app/routes/challenges/views/classic/index.js rename to common/app/routes/Challenges/views/classic/index.js diff --git a/common/app/routes/challenges/views/classic/ns.json b/common/app/routes/Challenges/views/classic/ns.json similarity index 100% rename from common/app/routes/challenges/views/classic/ns.json rename to common/app/routes/Challenges/views/classic/ns.json diff --git a/common/app/routes/challenges/views/index.less b/common/app/routes/Challenges/views/index.less similarity index 100% rename from common/app/routes/challenges/views/index.less rename to common/app/routes/Challenges/views/index.less diff --git a/common/app/routes/challenges/views/project/Forms.jsx b/common/app/routes/Challenges/views/project/Forms.jsx similarity index 98% rename from common/app/routes/challenges/views/project/Forms.jsx rename to common/app/routes/Challenges/views/project/Forms.jsx index 5138fdccaa..1bc9535ff5 100644 --- a/common/app/routes/challenges/views/project/Forms.jsx +++ b/common/app/routes/Challenges/views/project/Forms.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import { reduxForm } from 'redux-form'; import { Button, diff --git a/common/app/routes/challenges/views/project/Project.jsx b/common/app/routes/Challenges/views/project/Project.jsx similarity index 96% rename from common/app/routes/challenges/views/project/Project.jsx rename to common/app/routes/Challenges/views/project/Project.jsx index 1278903c6c..dcbe854099 100644 --- a/common/app/routes/challenges/views/project/Project.jsx +++ b/common/app/routes/Challenges/views/project/Project.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import { createSelector } from 'reselect'; import { connect } from 'react-redux'; import PureComponent from 'react-pure-render/component'; diff --git a/common/app/routes/challenges/views/project/Show.jsx b/common/app/routes/Challenges/views/project/Show.jsx similarity index 74% rename from common/app/routes/challenges/views/project/Show.jsx rename to common/app/routes/Challenges/views/project/Show.jsx index e3d470120f..cc6fd5751e 100644 --- a/common/app/routes/challenges/views/project/Show.jsx +++ b/common/app/routes/Challenges/views/project/Show.jsx @@ -1,16 +1,21 @@ import React from 'react'; +import ns from './ns.json'; import Main from './Project.jsx'; import { types } from '../../redux'; import Panes from '../../../../Panes'; +import { createPaneMap } from '../../../../Panes/redux'; import _Map from '../../../../Map'; import ChildContainer from '../../../../Child-Container.jsx'; const propTypes = {}; -export const panesMap = { - [types.toggleMap]: 'Map', - [types.toggleMain]: 'Main' -}; +export const panesMap = createPaneMap( + ns, + () => ({ + [types.toggleMap]: 'Map', + [types.toggleMain]: 'Main' + }) +); const nameToComponent = { Map: { diff --git a/common/app/routes/challenges/views/project/Side-Panel.jsx b/common/app/routes/Challenges/views/project/Side-Panel.jsx similarity index 91% rename from common/app/routes/challenges/views/project/Side-Panel.jsx rename to common/app/routes/Challenges/views/project/Side-Panel.jsx index 2b797f2ec5..b93a3a7b3f 100644 --- a/common/app/routes/challenges/views/project/Side-Panel.jsx +++ b/common/app/routes/Challenges/views/project/Side-Panel.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes, PureComponent } from 'react'; +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; import ChallengeTitle from '../../Challenge-Title.jsx'; const propTypes = { diff --git a/common/app/routes/challenges/views/project/Tool-Panel.jsx b/common/app/routes/Challenges/views/project/Tool-Panel.jsx similarity index 97% rename from common/app/routes/challenges/views/project/Tool-Panel.jsx rename to common/app/routes/Challenges/views/project/Tool-Panel.jsx index 68b25fb556..9335c29ce4 100644 --- a/common/app/routes/challenges/views/project/Tool-Panel.jsx +++ b/common/app/routes/Challenges/views/project/Tool-Panel.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import PureComponent from 'react-pure-render/component'; import { connect } from 'react-redux'; import { createSelector } from 'reselect'; diff --git a/common/app/routes/challenges/views/project/index.js b/common/app/routes/Challenges/views/project/index.js similarity index 100% rename from common/app/routes/challenges/views/project/index.js rename to common/app/routes/Challenges/views/project/index.js diff --git a/common/app/routes/challenges/views/project/ns.json b/common/app/routes/Challenges/views/project/ns.json similarity index 100% rename from common/app/routes/challenges/views/project/ns.json rename to common/app/routes/Challenges/views/project/ns.json diff --git a/common/app/routes/challenges/views/project/redux/index.js b/common/app/routes/Challenges/views/project/redux/index.js similarity index 60% rename from common/app/routes/challenges/views/project/redux/index.js rename to common/app/routes/Challenges/views/project/redux/index.js index 67bde420a6..18c5362e50 100644 --- a/common/app/routes/challenges/views/project/redux/index.js +++ b/common/app/routes/Challenges/views/project/redux/index.js @@ -1,5 +1,8 @@ -import { createTypes } from 'redux-create-types'; -import { createAction, handleActions } from 'redux-actions'; +import { + createAction, + createTypes, + handleActions +} from 'berkeleys-redux-utils'; import ns from '../ns.json'; export const types = createTypes([ @@ -14,14 +17,13 @@ const initialState = { }; export const submittingSelector = state => state[ns].isSubmitting; -export default function createReducer() { - const reducer = handleActions({ +export default handleActions( + () => ({ [types.showProjectSubmit]: state => ({ ...state, isSubmitting: true }) - }, initialState); - - reducer.toString = () => ns; - return [ reducer ]; -} + }), + initialState, + ns +); diff --git a/common/app/routes/challenges/views/project/redux/project-normalizer.js b/common/app/routes/Challenges/views/project/redux/project-normalizer.js similarity index 100% rename from common/app/routes/challenges/views/project/redux/project-normalizer.js rename to common/app/routes/Challenges/views/project/redux/project-normalizer.js diff --git a/common/app/routes/challenges/views/quiz/Choice.jsx b/common/app/routes/Challenges/views/quiz/Choice.jsx similarity index 95% rename from common/app/routes/challenges/views/quiz/Choice.jsx rename to common/app/routes/Challenges/views/quiz/Choice.jsx index 0ba6e9c7e9..86de3796e8 100644 --- a/common/app/routes/challenges/views/quiz/Choice.jsx +++ b/common/app/routes/Challenges/views/quiz/Choice.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes, PureComponent } from 'react'; +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import classnames from 'classnames'; diff --git a/common/app/routes/challenges/views/quiz/Quiz.jsx b/common/app/routes/Challenges/views/quiz/Quiz.jsx similarity index 98% rename from common/app/routes/challenges/views/quiz/Quiz.jsx rename to common/app/routes/Challenges/views/quiz/Quiz.jsx index d6490f2db0..1b376040c6 100644 --- a/common/app/routes/challenges/views/quiz/Quiz.jsx +++ b/common/app/routes/Challenges/views/quiz/Quiz.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes, PureComponent } from 'react'; +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import { createSelector } from 'reselect'; diff --git a/common/app/routes/challenges/views/quiz/Show.jsx b/common/app/routes/Challenges/views/quiz/Show.jsx similarity index 73% rename from common/app/routes/challenges/views/quiz/Show.jsx rename to common/app/routes/Challenges/views/quiz/Show.jsx index ab31f006a4..6b7fe113bb 100644 --- a/common/app/routes/challenges/views/quiz/Show.jsx +++ b/common/app/routes/Challenges/views/quiz/Show.jsx @@ -1,16 +1,21 @@ import React from 'react'; +import ns from './ns.json'; import Main from './Quiz.jsx'; import { types } from '../../redux'; import Panes from '../../../../Panes'; +import { createPaneMap } from '../../../../Panes/redux'; import _Map from '../../../../Map'; import ChildContainer from '../../../../Child-Container.jsx'; const propTypes = {}; -export const panesMap = { - [types.toggleMap]: 'Map', - [types.toggleMain]: 'Main' -}; +export const panesMap = createPaneMap( + ns, + () => ({ + [types.toggleMap]: 'Map', + [types.toggleMain]: 'Main' + }) +); const nameToComponent = { Map: { diff --git a/common/app/routes/challenges/views/quiz/index.js b/common/app/routes/Challenges/views/quiz/index.js similarity index 100% rename from common/app/routes/challenges/views/quiz/index.js rename to common/app/routes/Challenges/views/quiz/index.js diff --git a/common/app/routes/challenges/views/quiz/ns.json b/common/app/routes/Challenges/views/quiz/ns.json similarity index 100% rename from common/app/routes/challenges/views/quiz/ns.json rename to common/app/routes/Challenges/views/quiz/ns.json diff --git a/common/app/routes/challenges/views/quiz/quiz.less b/common/app/routes/Challenges/views/quiz/quiz.less similarity index 100% rename from common/app/routes/challenges/views/quiz/quiz.less rename to common/app/routes/Challenges/views/quiz/quiz.less diff --git a/common/app/routes/challenges/views/quiz/redux/index.js b/common/app/routes/Challenges/views/quiz/redux/index.js similarity index 84% rename from common/app/routes/challenges/views/quiz/redux/index.js rename to common/app/routes/Challenges/views/quiz/redux/index.js index ae31a5da3d..299511e734 100644 --- a/common/app/routes/challenges/views/quiz/redux/index.js +++ b/common/app/routes/Challenges/views/quiz/redux/index.js @@ -1,5 +1,8 @@ -import { createTypes } from 'redux-create-types'; -import { createAction, handleActions } from 'redux-actions'; +import { + createAction, + createTypes, + handleActions +} from 'berkeleys-redux-utils'; import noop from 'lodash/noop'; import ns from '../ns.json'; @@ -48,8 +51,8 @@ export const currentIndexSelector = state => getNS(state).currentIndex; export const selectedChoiceSelector = state => getNS(state).selectedChoice; export const correctSelector = state => getNS(state).correct; -export default function createReducers() { - const reducer = handleActions({ +export default handleActions( + () => ({ [types.nextQuestion]: state => ({ ...state, currentIndex: state.currentIndex + 1 @@ -72,8 +75,7 @@ export default function createReducers() { ...state, selectedChoice: null }) - }, initialState); - - reducer.toString = () => ns; - return [ reducer ]; -} + }), + initialState, + ns +); diff --git a/common/app/routes/challenges/views/step/Show.jsx b/common/app/routes/Challenges/views/step/Show.jsx similarity index 73% rename from common/app/routes/challenges/views/step/Show.jsx rename to common/app/routes/Challenges/views/step/Show.jsx index 81425940e2..67fa13963f 100644 --- a/common/app/routes/challenges/views/step/Show.jsx +++ b/common/app/routes/Challenges/views/step/Show.jsx @@ -1,16 +1,21 @@ import React from 'react'; +import ns from './ns.json'; import Step from './Step.jsx'; import { types } from '../../redux'; import Panes from '../../../../Panes'; +import { createPaneMap } from '../../../../Panes/redux'; import _Map from '../../../../Map'; import ChildContainer from '../../../../Child-Container.jsx'; const propTypes = {}; -export const panesMap = { - [types.toggleMap]: 'Map', - [types.toggleStep]: 'Step' -}; +export const panesMap = createPaneMap( + ns, + () => ({ + [types.toggleMap]: 'Map', + [types.toggleStep]: 'Step' + }) +); const nameToComponent = { Map: { diff --git a/common/app/routes/challenges/views/step/Step.jsx b/common/app/routes/Challenges/views/step/Step.jsx similarity index 98% rename from common/app/routes/challenges/views/step/Step.jsx rename to common/app/routes/Challenges/views/step/Step.jsx index 84cdb9297d..1038350dda 100644 --- a/common/app/routes/challenges/views/step/Step.jsx +++ b/common/app/routes/Challenges/views/step/Step.jsx @@ -1,4 +1,5 @@ -import React, { PropTypes, PureComponent } from 'react'; +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import classnames from 'classnames'; diff --git a/common/app/routes/challenges/views/step/index.js b/common/app/routes/Challenges/views/step/index.js similarity index 100% rename from common/app/routes/challenges/views/step/index.js rename to common/app/routes/Challenges/views/step/index.js diff --git a/common/app/routes/challenges/views/step/ns.json b/common/app/routes/Challenges/views/step/ns.json similarity index 100% rename from common/app/routes/challenges/views/step/ns.json rename to common/app/routes/Challenges/views/step/ns.json diff --git a/common/app/routes/challenges/views/step/redux/index.js b/common/app/routes/Challenges/views/step/redux/index.js similarity index 89% rename from common/app/routes/challenges/views/step/redux/index.js rename to common/app/routes/Challenges/views/step/redux/index.js index b744c9d22d..98d0ac9dc1 100644 --- a/common/app/routes/challenges/views/step/redux/index.js +++ b/common/app/routes/Challenges/views/step/redux/index.js @@ -1,5 +1,9 @@ -import { createTypes } from 'redux-create-types'; -import { createAction, handleActions } from 'redux-actions'; +import { + createAction, + createTypes, + handleActions +} from 'berkeleys-redux-utils'; + import noop from 'lodash/noop'; import stepChallengeEpic from './step-challenge-epic.js'; @@ -57,8 +61,8 @@ export const unlockedStepsSelector = state => getNS(state).unlockedSteps; export const lightBoxSelector = state => getNS(state).isLightBoxOpen; export const actionCompletedSelector = state => getNS(state).isActionCompleted; -export default function createReducers() { - const reducer = handleActions({ +export default handleActions( + () => ({ [challenges.challengeUpdated]: () => { console.log('updating step ui'); return initialState; @@ -85,8 +89,7 @@ export default function createReducers() { ...state, isLightBoxOpen: false }) - }, initialState); - - reducer.toString = () => ns; - return [ reducer ]; -} + }), + initialState, + ns +); diff --git a/common/app/routes/challenges/views/step/redux/step-challenge-epic.js b/common/app/routes/Challenges/views/step/redux/step-challenge-epic.js similarity index 100% rename from common/app/routes/challenges/views/step/redux/step-challenge-epic.js rename to common/app/routes/Challenges/views/step/redux/step-challenge-epic.js diff --git a/common/app/routes/challenges/views/step/redux/step-challenge-epic.test.js b/common/app/routes/Challenges/views/step/redux/step-challenge-epic.test.js similarity index 95% rename from common/app/routes/challenges/views/step/redux/step-challenge-epic.test.js rename to common/app/routes/Challenges/views/step/redux/step-challenge-epic.test.js index 3aaf04aee2..bb970f31ff 100644 --- a/common/app/routes/challenges/views/step/redux/step-challenge-epic.test.js +++ b/common/app/routes/Challenges/views/step/redux/step-challenge-epic.test.js @@ -6,7 +6,7 @@ import sinon from 'sinon'; import ns from '../ns.json'; // import challenges.redux to get around // circular dependency -import { types as app } from '../../../redux'; +import { types as challenge } from '../../../redux'; import { types } from './'; config.longStackSupport = true; @@ -16,7 +16,7 @@ const stepChallengeEpic = proxy( { '../../../../../redux': challengeSelectorStub } ); -const file = 'common/app/routes/challenges/redux/step-challenge-epic'; +const file = 'common/app/routes/Challenges/redux/step-challenge-epic'; test(file, function(t) { t.test('does not respond to random actions', t => { const actions = Observable.of({ type: 'NotTheMomma' }); @@ -134,7 +134,7 @@ test(file, function(t) { ); t.assert( onNextSpy.calledWithMatch({ - type: app.submitChallenge + type: challenge.submitChallenge.toString() }), 'Epic did not return the expected action' ); diff --git a/common/app/routes/challenges/views/step/step.less b/common/app/routes/Challenges/views/step/step.less similarity index 100% rename from common/app/routes/challenges/views/step/step.less rename to common/app/routes/Challenges/views/step/step.less diff --git a/common/app/routes/Map/index.js b/common/app/routes/Map/index.js new file mode 100644 index 0000000000..9c0750e66f --- /dev/null +++ b/common/app/routes/Map/index.js @@ -0,0 +1,10 @@ +import { types as map } from '../../Map/redux'; +import { onRouteCurrentChallenge } from '../Challenges/redux'; + +export const routes = { + [map.onRouteMap]: { + type: map.onRouteMap, + path: '/map', + redirect: onRouteCurrentChallenge + } +}; diff --git a/common/app/routes/settings/Email-Setting.jsx b/common/app/routes/Settings/Email-Setting.jsx similarity index 96% rename from common/app/routes/settings/Email-Setting.jsx rename to common/app/routes/Settings/Email-Setting.jsx index 0016f01945..2cf9700d34 100644 --- a/common/app/routes/settings/Email-Setting.jsx +++ b/common/app/routes/Settings/Email-Setting.jsx @@ -1,5 +1,5 @@ -import React, { PropTypes } from 'react'; -import { Link } from 'react-router'; +import PropTypes from 'prop-types'; +import React from 'react'; import { ToggleButtonGroup, ToggleButton, @@ -10,6 +10,9 @@ import { import FA from 'react-fontawesome'; import classnames from 'classnames'; +import { onRouteUpdateEmail } from './redux'; +import { Link } from '../../Router'; + const propTypes = { email: PropTypes.string, sendMonthlyEmail: PropTypes.bool, @@ -24,7 +27,7 @@ export function UpdateEmailButton() { return (
- + - + diff --git a/common/app/routes/settings/routes/update-email/index.js b/common/app/routes/Settings/routes/update-email/index.js similarity index 100% rename from common/app/routes/settings/routes/update-email/index.js rename to common/app/routes/Settings/routes/update-email/index.js diff --git a/common/app/routes/settings/settings.less b/common/app/routes/Settings/settings.less similarity index 100% rename from common/app/routes/settings/settings.less rename to common/app/routes/Settings/settings.less diff --git a/common/app/routes/challenges/Show.jsx b/common/app/routes/challenges/Show.jsx deleted file mode 100644 index edd3bae482..0000000000 --- a/common/app/routes/challenges/Show.jsx +++ /dev/null @@ -1,140 +0,0 @@ -import React, { PropTypes } from 'react'; -import { compose } from 'redux'; -import { contain } from 'redux-epic'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import PureComponent from 'react-pure-render/component'; - -import CompletionModal from './Completion-Modal.jsx'; -import Classic from './views/classic'; -import Step from './views/step'; -import Project from './views/project'; -import BackEnd from './views/backend'; -import Quiz from './views/quiz'; - -import { challengeMetaSelector } from './redux'; -import { - updateTitle, - updateCurrentChallenge, - fetchChallenge, - - challengeSelector, - langSelector -} from '../../redux'; -import { makeToast } from '../../Toasts/redux'; - -const views = { - backend: BackEnd, - classic: Classic, - project: Project, - simple: Project, - step: Step, - quiz: Quiz -}; - -const mapDispatchToProps = { - fetchChallenge, - makeToast, - updateCurrentChallenge, - updateTitle -}; - -const mapStateToProps = createSelector( - challengeSelector, - challengeMetaSelector, - langSelector, - ( - { dashedName, isTranslated }, - { viewType, title }, - lang - ) => ({ - lang, - isTranslated, - title, - challenge: dashedName, - viewType - }) -); - -const fetchOptions = { - fetchAction: 'fetchChallenge', - getActionArgs({ params: { block, dashedName } }) { - return [ dashedName, block ]; - }, - isPrimed({ challenge }) { - return !!challenge; - } -}; - -const link = 'http://forum.freecodecamp.org/t/' + - 'guidelines-for-translating-free-code-camp' + - '-to-any-language/19111'; - -const propTypes = { - areChallengesLoaded: PropTypes.bool, - isStep: PropTypes.bool, - isTranslated: PropTypes.bool, - lang: PropTypes.string.isRequired, - makeToast: PropTypes.func.isRequired, - params: PropTypes.object.isRequired, - title: PropTypes.string, - updateCurrentChallenge: PropTypes.func.isRequired, - updateTitle: PropTypes.func.isRequired, - viewType: PropTypes.string - }; - -export class Show extends PureComponent { - componentWillMount() { - const { lang, isTranslated, makeToast } = this.props; - if (lang !== 'en' && !isTranslated) { - makeToast({ - message: 'We haven\'t translated this challenge yet.', - action: Help Us, - timeout: 15000 - }); - } - } - - componentDidMount() { - if (this.props.title) { - this.props.updateTitle(this.props.title); - } - } - - componentWillReceiveProps(nextProps) { - const { title } = nextProps; - const { dashedName } = nextProps.params; - const { lang, isTranslated } = nextProps; - const { updateTitle, updateCurrentChallenge, makeToast } = this.props; - if (this.props.params.dashedName !== dashedName) { - updateCurrentChallenge(dashedName); - updateTitle(title); - if (lang !== 'en' && !isTranslated) { - makeToast({ - message: 'We haven\'t translated this challenge yet.', - action: Help Us, - timeout: 15000 - }); - } - } - } - - render() { - const { viewType } = this.props; - const View = views[viewType] || Classic; - return ( -
- - -
- ); - } -} - -Show.displayName = 'Show(ChallengeView)'; -Show.propTypes = propTypes; - -export default compose( - connect(mapStateToProps, mapDispatchToProps), - contain(fetchOptions) -)(Show); diff --git a/common/app/routes/challenges/index.js b/common/app/routes/challenges/index.js deleted file mode 100644 index a0eea2dd3e..0000000000 --- a/common/app/routes/challenges/index.js +++ /dev/null @@ -1,32 +0,0 @@ -import Show from './Show.jsx'; -import { panesMap as backendPanesMap } from './views/backend'; -import { panesMap as classicPanesMap } from './views/classic'; -import { panesMap as stepPanesMap } from './views/step'; -import { panesMap as projectPanesMap } from './views/project'; -import { panesMap as quizPanesMap } from './views/quiz'; - -export function createPanesMap() { - return { - ...backendPanesMap, - ...classicPanesMap, - ...stepPanesMap, - ...projectPanesMap, - ...quizPanesMap - }; -} - -export default function challengesRoutes() { - return [{ - path: 'challenges(/:dashedName)', - component: Show, - onEnter(nextState, replace) { - // redirect /challenges to /map - if (nextState.location.pathname === '/challenges') { - replace('/challenges/current-challenge'); - } - } - }, { - path: 'challenges/:block/:dashedName', - component: Show - }]; -} diff --git a/common/app/routes/index.js b/common/app/routes/index.js index ba2e0f7234..c925d4ee64 100644 --- a/common/app/routes/index.js +++ b/common/app/routes/index.js @@ -1,27 +1,32 @@ -import challenges from './challenges'; -import map from './map'; -import settings from './settings'; +import { routes as challengesRoutes } from './Challenges'; +import { routes as mapRoutes } from './Map'; +import { routes as settingsRoutes } from './Settings'; -import NotFound from '../NotFound'; -import { addLang } from '../utils/lang'; +// import { addLang } from '../utils/lang'; -export { createPanesMap } from './challenges'; +export { createPanesMap } from './Challenges'; -export default function createChildRoute(deps) { - return { - path: '/:lang', - indexRoute: { - onEnter(nextState, replace) { - const { lang } = nextState.params; - const { pathname } = nextState.location; - replace(addLang(pathname, lang)); - } - }, - childRoutes: [ - ...challenges(deps), - ...map(deps), - ...settings(deps), - { path: '*', component: NotFound } - ] - }; -} +export default { + ...challengesRoutes, + ...mapRoutes, + ...settingsRoutes +}; + +// export default function createChildRoute(deps) { +// return { +// path: '/:lang', +// indexRoute: { +// onEnter(nextState, replace) { +// const { lang } = nextState.params; +// const { pathname } = nextState.location; +// replace(addLang(pathname, lang)); +// } +// }, +// childRoutes: [ +// ...challenges(deps), +// ...map(deps), +// ...settings(deps), +// { path: '*', component: NotFound } +// ] +// }; +// } diff --git a/common/app/routes/index.less b/common/app/routes/index.less index af0f7d4506..6a049183c3 100644 --- a/common/app/routes/index.less +++ b/common/app/routes/index.less @@ -1,2 +1,2 @@ -&{ @import "./challenges/challenges.less"; } -&{ @import "./settings/settings.less"; } \ No newline at end of file +&{ @import "./Challenges/challenges.less"; } +&{ @import "./Settings/settings.less"; } diff --git a/common/app/routes/map/index.js b/common/app/routes/map/index.js deleted file mode 100644 index 91e74e5838..0000000000 --- a/common/app/routes/map/index.js +++ /dev/null @@ -1,6 +0,0 @@ -export default function mapRoute() { - return [{ - path: 'map', - onEnter: (_, replace) => replace('/challenges/current-challenge') - }]; -} diff --git a/common/app/routes/redux.js b/common/app/routes/redux.js index ecd8b12c00..f0f82a875d 100644 --- a/common/app/routes/redux.js +++ b/common/app/routes/redux.js @@ -1,7 +1,34 @@ -import createChallengesReducer from './challenges/redux'; +import { isLocationAction } from 'redux-first-router'; +import { combineReducers } from 'berkeleys-redux-utils'; -export default function createReducers() { - return [ - ...createChallengesReducer() - ]; + +import challengeReducer from './Challenges/redux'; +import settingsReducer from './Settings/redux'; +import { routes as challengeRoutes } from './Challenges'; +import { routes as settingsRoutes } from './Settings'; + +const ns = 'mainRouter'; + +export const mainRouteSelector = state => state[ns]; + +export function mainRouter(state = 'NotFound', action) { + if (!isLocationAction(action)) { + return state; + } + const { type } = action; + if (challengeRoutes[type]) { + return 'challenges'; + } + if (settingsRoutes[type]) { + return 'settings'; + } + return ''; } + +mainRouter.toString = () => ns; + +export default combineReducers( + challengeReducer, + settingsReducer, + mainRouter +); diff --git a/common/app/routes/settings/index.js b/common/app/routes/settings/index.js deleted file mode 100644 index 366f1de25c..0000000000 --- a/common/app/routes/settings/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import Settings from './Settings.jsx'; -import updateEmailRoute from './routes/update-email'; - -export default function settingsRoute(deps) { - return [{ - path: 'settings', - component: Settings, - childRoutes: updateEmailRoute(deps) - }]; -} diff --git a/common/app/routes/settings/redux/index.js b/common/app/routes/settings/redux/index.js deleted file mode 100644 index 085cca21ed..0000000000 --- a/common/app/routes/settings/redux/index.js +++ /dev/null @@ -1,21 +0,0 @@ -import { createTypes } from 'redux-create-types'; -import { createAction } from 'redux-actions'; - -import userUpdateEpic from './update-user-epic.js'; - -export const epics = [ - userUpdateEpic -]; - -export const types = createTypes([ - 'toggleUserFlag', - 'updateMyEmail', - 'updateMyLang' -], 'settings'); - -export const toggleUserFlag = createAction(types.toggleUserFlag); -export const updateMyEmail = createAction(types.updateMyEmail); -export const updateMyLang = createAction( - types.updateMyLang, - (values) => values.lang -); diff --git a/common/app/utils/No-Props-Passthrough.jsx b/common/app/utils/No-Props-Passthrough.jsx index d0ab31cd7f..66281c5e87 100644 --- a/common/app/utils/No-Props-Passthrough.jsx +++ b/common/app/utils/No-Props-Passthrough.jsx @@ -1,4 +1,4 @@ -import { PropTypes } from 'react'; +import PropTypes from 'prop-types'; // use when passing a react primitive element as a child to a // react-boostrap component that will inject props diff --git a/common/app/utils/classic-file.js b/common/app/utils/classic-file.js new file mode 100644 index 0000000000..465ea65b35 --- /dev/null +++ b/common/app/utils/classic-file.js @@ -0,0 +1,33 @@ +import flow from 'lodash/flow'; +import { decodeScriptTags } from '../../utils/encode-decode.js'; +import * as challengeTypes from './challengeTypes.js'; + +export function arrayToString(seedData = ['']) { + seedData = Array.isArray(seedData) ? seedData : [seedData]; + return seedData.reduce((seed, line) => '' + seed + line + '\n', '\n'); +} + +export function buildSeed({ challengeSeed = [] } = {}) { + return flow( + arrayToString, + decodeScriptTags + )(challengeSeed); +} + +const pathsMap = { + [ challengeTypes.html ]: 'html', + [ challengeTypes.js ]: 'js', + [ challengeTypes.bonfire ]: 'js' +}; + +export function getPreFile({ challengeType }) { + return { + name: 'index', + ext: pathsMap[challengeType] || 'html', + key: getFileKey({ challengeType }) + }; +} + +export function getFileKey({ challengeType }) { + return 'index' + (pathsMap[challengeType] || 'html'); +} diff --git a/common/app/utils/redux-first-router.js b/common/app/utils/redux-first-router.js new file mode 100644 index 0000000000..e03cabf4a0 --- /dev/null +++ b/common/app/utils/redux-first-router.js @@ -0,0 +1,26 @@ +import invariant from 'invariant'; +import { redirect as createRedirect } from 'redux-first-router'; + +import routesMap from '../routes-map.js'; +import { langSelector } from '../Router/redux'; + +export function onBeforeChange(dispatch, getState, action) { + const route = routesMap[action.type]; + const lang = langSelector(getState()); + if (route && route.redirect) { + invariant( + typeof route.redirect === 'function', + ` + route redirect should be a function but got %s + check the redirect method of route %s + `, + route.redirect, + route + ); + return dispatch(createRedirect(route.redirect({ lang }))); + } + return action; +} + +// prevent function from serializing during SSR +onBeforeChange.toString = () => 'onBeforeChange'; diff --git a/common/utils/wait-for-epics.js b/common/utils/wait-for-epics.js new file mode 100644 index 0000000000..f847de16b7 --- /dev/null +++ b/common/utils/wait-for-epics.js @@ -0,0 +1,15 @@ +import { Observable } from 'rx'; +import debug from 'debug'; + +const log = debug('redux-epic:waitForEpics'); + +// waitForEpics(epicMiddleware: EpicMiddleware) => Observable[Void] +export default function waitForEpics(epicMiddleware) { + return Observable.defer(() => { + log('calling actions onCompleted'); + epicMiddleware.end(); + return Observable.merge(epicMiddleware); + }) + .last({ defaultValue: null }) + .map(() => epicMiddleware.restart()); +} diff --git a/package-lock.json b/package-lock.json index 0596d3d349..8a8563abf1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,17 +10,17 @@ "integrity": "sha1-z6I7xYQPkQTOMqZedNt+epdLvuE=", "dev": true, "requires": { - "acorn": "5.1.1", + "acorn": "5.2.1", "css": "2.2.1", "normalize-path": "2.1.1", - "source-map": "0.5.6", + "source-map": "0.5.7", "through2": "2.0.3" }, "dependencies": { "acorn": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.1.tgz", - "integrity": "sha512-vOk6uEMctu0vQrvuSqFdJyqj1Q0S5VTDL79qtjo+DhRr+1mmaD+tluFSCZqhvi/JUhXSzoZN2BhtstaPEeE8cw==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", "dev": true }, "css": { @@ -45,6 +45,15 @@ } } } + }, + "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" + } } } }, @@ -56,47 +65,68 @@ "requires": { "normalize-path": "2.1.1", "through2": "2.0.3" + }, + "dependencies": { + "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" + } + } } }, "@types/bluebird": { - "version": "3.5.8", - "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.8.tgz", - "integrity": "sha512-rBfrD56OxaqVjghtVqp2EEX0ieHkRk6IefDVrQXIVGvlhDOEBTvZff4Q02uo84ukVkH4k5eB1cPKGDM2NlFL8A==" + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.18.tgz", + "integrity": "sha512-OTPWHmsyW18BhrnG5x8F7PzeZ2nFxmHGb42bZn79P9hl+GI5cMzyPgQTwNjbem0lJhoru/8vtjAFCUOu3+gE2w==" + }, + "@types/body-parser": { + "version": "1.16.7", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.16.7.tgz", + "integrity": "sha512-Obn1/GG0sYsnlAlhhSR1hvYRGBpQT+fzSi2IlGN8emCE4iu6f6xIjaq499B1sa7N9iBLzxyOUBo5bzgJd16BvA==", + "requires": { + "@types/express": "4.0.39", + "@types/node": "8.0.47" + } }, "@types/express": { - "version": "4.0.36", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.0.36.tgz", - "integrity": "sha512-bT9q2eqH/E72AGBQKT50dh6AXzheTqigGZ1GwDiwmx7vfHff0bZOrvUWjvGpNWPNkRmX1vDF6wonG6rlpBHb1A==", + "version": "4.0.39", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.0.39.tgz", + "integrity": "sha512-dBUam7jEjyuEofigUXCtublUHknRZvcRgITlGsTbFgPvnTwtQUt2NgLakbsf+PsGo/Nupqr3IXCYsOpBpofyrA==", "requires": { - "@types/express-serve-static-core": "4.0.49", - "@types/serve-static": "1.7.31" + "@types/body-parser": "1.16.7", + "@types/express-serve-static-core": "4.0.56", + "@types/serve-static": "1.13.0" } }, "@types/express-serve-static-core": { - "version": "4.0.49", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.0.49.tgz", - "integrity": "sha512-b7mVHoURu1xaP/V6xw1sYwyv9V0EZ7euyi+sdnbnTZxEkAh4/hzPsI6Eflq+ZzHQ/Tgl7l16Jz+0oz8F46MLnA==", + "version": "4.0.56", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.0.56.tgz", + "integrity": "sha512-/0nwIzF1Bd4KGwW4lhDZYi5StmCZG1DIXXMfQ/zjORzlm4+F1eRA4c6yJQrt4hqX//TDtPULpSlYwmSNyCMeMg==", "requires": { - "@types/node": "6.0.81" + "@types/node": "8.0.47" } }, "@types/mime": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.1.tgz", - "integrity": "sha512-rek8twk9C58gHYqIrUlJsx8NQMhlxqHzln9Z9ODqiNgv3/s+ZwIrfr+djqzsnVM12xe9hL98iJ20lj2RvCBv6A==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.0.tgz", + "integrity": "sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA==" }, "@types/node": { - "version": "6.0.81", - "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.81.tgz", - "integrity": "sha512-KdtXOH8l9O2wwOOX+swjbFx+YW/RJFfI14o6S50+Zy79FK1WFGkzFdDsiuNjrG5L6FaBSKpKzSpWgTvXurbbYg==" + "version": "8.0.47", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.47.tgz", + "integrity": "sha512-kOwL746WVvt/9Phf6/JgX/bsGQvbrK5iUgzyfwZNcKVFcjAUVSpF9HxevLTld2SG9aywYHOILj38arDdY1r/iQ==" }, "@types/serve-static": { - "version": "1.7.31", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.7.31.tgz", - "integrity": "sha1-FUVt6NmNa0z/Mb5savdJKuY/Uho=", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.0.tgz", + "integrity": "sha512-wvQkePwCDZoyQPGb64DTl2TEeLw54CQFXjY+tznxYYxNcBb4LG40ezoVbMDa0epwE4yogB0f42jCaH0356x5Mg==", "requires": { - "@types/express-serve-static-core": "4.0.49", - "@types/mime": "1.3.1" + "@types/express-serve-static-core": "4.0.56", + "@types/mime": "2.0.0" } }, "JSONStream": { @@ -114,16 +144,16 @@ "integrity": "sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c=" }, "abbrev": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz", - "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "accepts": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", - "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", + "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", "requires": { - "mime-types": "2.1.15", + "mime-types": "2.1.17", "negotiator": "0.6.1" } }, @@ -143,8 +173,8 @@ "lodash.partialright": "4.2.1", "lodash.pick": "4.4.0", "lodash.uniq": "4.5.0", - "resolve": "1.3.3", - "semver": "5.3.0", + "resolve": "1.5.0", + "semver": "5.4.1", "uglify-js": "2.8.29", "when": "3.7.8" } @@ -202,14 +232,22 @@ "integrity": "sha1-asL8ICtQD4jaj09VMM+hAPTGotA=" }, "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.3.0.tgz", + "integrity": "sha1-RBT/dKUIecII7l/cgm4ywwNUnto=", "requires": { "co": "4.6.0", - "json-stable-stringify": "1.0.1" + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" } }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, "align-text": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", @@ -225,6 +263,48 @@ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" }, + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "dev": true, + "requires": { + "string-width": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, "ansi-escapes": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", @@ -252,13 +332,24 @@ "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=" }, "anymatch": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz", - "integrity": "sha1-o+Uvo5FoyCX/V7AkgSbOWo/5VQc=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", "dev": true, "requires": { - "arrify": "1.0.1", - "micromatch": "2.3.11" + "micromatch": "2.3.11", + "normalize-path": "2.1.1" + }, + "dependencies": { + "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" + } + } } }, "aphrodite": { @@ -327,6 +418,16 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "1.1.2", + "es-abstract": "1.9.0" + } + }, "array-slice": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.0.0.tgz", @@ -352,16 +453,6 @@ "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", "dev": true }, - "array.prototype.find": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.0.4.tgz", - "integrity": "sha1-VWpcU2LAhkgyPdrrnenRS8GGTJA=", - "dev": true, - "requires": { - "define-properties": "1.1.2", - "es-abstract": "1.7.0" - } - }, "arraybuffer.slice": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", @@ -393,9 +484,9 @@ } }, "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, "assertion-error": { "version": "1.0.2", @@ -431,11 +522,11 @@ "dev": true }, "async-listener": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.7.tgz", - "integrity": "sha512-6Bmzy9dHE1WWZdru7teS6kecmOy42cCzumQOn57vHa/49kjPMExdPLozDvr25J0hbQf5wMwFitJKnO7O3eqh2A==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.8.tgz", + "integrity": "sha512-1Sy1jDhjlgxcSd9/ICHqiAHT8VSJ9R1lzEyWwP/4Hm9p8nVTNtU0SxG/Z15XHD/aZvQraSw9BpDU3EBcFnOVrw==", "requires": { - "semver": "5.3.0", + "semver": "5.4.1", "shimmer": "1.1.0" } }, @@ -451,9 +542,9 @@ "dev": true }, "aws-sdk": { - "version": "2.83.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.83.0.tgz", - "integrity": "sha1-8BBxg1dtLmCTY2q4nM2bVGpTG+c=", + "version": "2.141.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.141.0.tgz", + "integrity": "sha1-PZallw/Z9UDOq8wdS66zO3FYOqc=", "requires": { "buffer": "4.9.1", "crypto-browserify": "1.0.9", @@ -462,27 +553,53 @@ "querystring": "0.2.0", "sax": "1.2.1", "url": "0.10.3", - "uuid": "3.0.1", + "uuid": "3.1.0", "xml2js": "0.4.17", "xmlbuilder": "4.2.1" }, "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + }, "sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" }, - "uuid": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz", - "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=" + "url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "xml2js": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz", + "integrity": "sha1-F76T6q4/O3eTWceVtBlwWogX6Gg=", + "requires": { + "sax": "1.2.1", + "xmlbuilder": "4.2.1" + } + }, + "xmlbuilder": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz", + "integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=", + "requires": { + "lodash": "4.17.4" + } } } }, "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=" + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { "version": "1.6.0", @@ -490,15 +607,15 @@ "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" }, "babel-cli": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.24.1.tgz", - "integrity": "sha1-IHzXBbumFImy6kG1MSNBz2rKIoM=", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", + "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", "dev": true, "requires": { - "babel-core": "6.25.0", - "babel-polyfill": "6.23.0", - "babel-register": "6.24.1", - "babel-runtime": "6.23.0", + "babel-core": "6.26.0", + "babel-polyfill": "6.26.0", + "babel-register": "6.26.0", + "babel-runtime": "6.26.0", "chokidar": "1.7.0", "commander": "2.11.0", "convert-source-map": "1.5.0", @@ -508,7 +625,7 @@ "output-file-sync": "1.1.2", "path-is-absolute": "1.0.1", "slash": "1.0.0", - "source-map": "0.5.6", + "source-map": "0.5.7", "v8flags": "2.1.1" }, "dependencies": { @@ -521,9 +638,9 @@ } }, "babel-code-frame": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", - "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "requires": { "chalk": "1.1.3", "esutils": "2.0.2", @@ -531,55 +648,197 @@ } }, "babel-core": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.25.0.tgz", - "integrity": "sha1-fdQrBGPHQunVKW3rPsZ6kyLa1yk=", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", + "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", "requires": { - "babel-code-frame": "6.22.0", - "babel-generator": "6.25.0", + "babel-code-frame": "6.26.0", + "babel-generator": "6.26.0", "babel-helpers": "6.24.1", "babel-messages": "6.23.0", - "babel-register": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0", - "babylon": "6.17.4", + "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", + "debug": "2.6.9", "json5": "0.5.1", "lodash": "4.17.4", "minimatch": "3.0.4", "path-is-absolute": "1.0.1", - "private": "0.1.7", + "private": "0.1.8", "slash": "1.0.0", - "source-map": "0.5.6" + "source-map": "0.5.7" } }, "babel-eslint": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz", - "integrity": "sha1-sv4tgBJkcPXBlELcdXJTqJdxCCc=", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-8.0.1.tgz", + "integrity": "sha512-h3moF6PCTQE06UjMMG+ydZSBvZ4Q7rqPE/5WAUOvUyHYUTqxm8JVhjZRiG1avI/tGVOK4BnZLDQapyLzh8DeKg==", "dev": true, "requires": { - "babel-code-frame": "6.22.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0", - "babylon": "6.17.4" + "babel-code-frame": "7.0.0-beta.0", + "babel-traverse": "7.0.0-beta.0", + "babel-types": "7.0.0-beta.0", + "babylon": "7.0.0-beta.22" + }, + "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" + } + }, + "babel-code-frame": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-7.0.0-beta.0.tgz", + "integrity": "sha512-/xr1ADm5bnTjjN+xwoXb7lF4v2rnxMzNZzFU7h8SxB+qB6+IqSTOOqVcpaPTUC2Non/MbQxS3OIZnJpQ2X21aQ==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "babel-helper-function-name": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-7.0.0-beta.0.tgz", + "integrity": "sha512-DaQccFBBWBEzMdqbKmNXamY0m1yLHJGOdbbEsNoGdJrrU7wAF3wwowtDDPzF0ZT3SqJXPgZW/P2kgBX9moMuAA==", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "7.0.0-beta.0", + "babel-template": "7.0.0-beta.0", + "babel-traverse": "7.0.0-beta.0", + "babel-types": "7.0.0-beta.0" + } + }, + "babel-helper-get-function-arity": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-7.0.0-beta.0.tgz", + "integrity": "sha512-csqAic15/2Vm1951nJxkkL9K8E6ojyNF/eAOjk7pqJlO8kvgrccGNFCV9eDwcGHDPe5AjvJGwVSAcQ5fit9wuA==", + "dev": true, + "requires": { + "babel-types": "7.0.0-beta.0" + } + }, + "babel-messages": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-7.0.0-beta.0.tgz", + "integrity": "sha512-eXdShsm9ZTh9AQhlIaAn6HR3xWpxCnK9ZwIDA9QyjnwTgMctGxHHflw4b4RJ3/ZjTL0Vrmvm0tQXPkp49mTAUw==", + "dev": true + }, + "babel-template": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-7.0.0-beta.0.tgz", + "integrity": "sha512-tmdH+MmmU0F6Ur8humpevSmFzYKbrN3Oru0g5Qyg4R6+sxjnzZmnvzUbsP0aKMr7tB0Ua6xhEb9arKTOsEMkyA==", + "dev": true, + "requires": { + "babel-traverse": "7.0.0-beta.0", + "babel-types": "7.0.0-beta.0", + "babylon": "7.0.0-beta.22", + "lodash": "4.17.4" + } + }, + "babel-traverse": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-7.0.0-beta.0.tgz", + "integrity": "sha512-IKzuTqUcQtMRZ0Vv5RjIrGGj33eBKmNTNeRexWSyjPPuAciyNkva1rt7WXPfHfkb+dX7coRAIUhzeTUEzhnwdA==", + "dev": true, + "requires": { + "babel-code-frame": "7.0.0-beta.0", + "babel-helper-function-name": "7.0.0-beta.0", + "babel-messages": "7.0.0-beta.0", + "babel-types": "7.0.0-beta.0", + "babylon": "7.0.0-beta.22", + "debug": "3.1.0", + "globals": "10.2.0", + "invariant": "2.2.2", + "lodash": "4.17.4" + } + }, + "babel-types": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-7.0.0-beta.0.tgz", + "integrity": "sha512-rJc2kV9iPJGLlqIY71AM3nPcdkoeLRCDuR07GFgfd3lFl4TsBQq76TxYQQIZ2MONg1HpsqmuoCXr9aZ1Oa4wYw==", + "dev": true, + "requires": { + "esutils": "2.0.2", + "lodash": "4.17.4", + "to-fast-properties": "2.0.0" + } + }, + "babylon": { + "version": "7.0.0-beta.22", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.22.tgz", + "integrity": "sha512-Yl7iT8QGrS8OfR7p6R12AJexQm+brKwrryai4VWZ7NHUbPoZ5al3+klhvl/14shXZiLa7uK//OIFuZ1/RKHgoA==", + "dev": true + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "globals": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-10.2.0.tgz", + "integrity": "sha512-Kqkw0LTOBKEwtVuBiw52QwD6qI1TkJZQKdIYUfVEitfPbSiSmclVicQV0hPS3oqVBkr+O/TPpKk7+dRn1h5Hog==", + "dev": true + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } } }, "babel-generator": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.25.0.tgz", - "integrity": "sha1-M6GvcNXyiQrrRlpKd5PB32qeqfw=", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz", + "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=", "requires": { "babel-messages": "6.23.0", - "babel-runtime": "6.23.0", - "babel-types": "6.25.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.6", + "source-map": "0.5.7", "trim-right": "1.0.1" } }, @@ -589,9 +848,9 @@ "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", "dev": true, "requires": { - "babel-runtime": "6.23.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-builder-binary-assignment-operator-visitor": { @@ -601,17 +860,17 @@ "dev": true, "requires": { "babel-helper-explode-assignable-expression": "6.24.1", - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-builder-react-jsx": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.24.1.tgz", - "integrity": "sha1-CteRfjPI11HmRtrKTnfMGTd9LLw=", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz", + "integrity": "sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA=", "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", "esutils": "2.0.2" } }, @@ -621,19 +880,19 @@ "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", "requires": { "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.23.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-define-map": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz", - "integrity": "sha1-epdH8ljYlH0y1RX2qhx70CIEoIA=", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", "requires": { "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.23.0", - "babel-types": "6.25.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", "lodash": "4.17.4" } }, @@ -643,9 +902,9 @@ "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", "dev": true, "requires": { - "babel-runtime": "6.23.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-explode-class": { @@ -655,9 +914,9 @@ "dev": true, "requires": { "babel-helper-bindify-decorators": "6.24.1", - "babel-runtime": "6.23.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-function-name": { @@ -666,10 +925,10 @@ "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", "requires": { "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-get-function-arity": { @@ -677,8 +936,8 @@ "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-hoist-variables": { @@ -686,8 +945,8 @@ "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-optimise-call-expression": { @@ -695,17 +954,17 @@ "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz", - "integrity": "sha1-024i+rEAjXnYhkjjIRaGgShFbOg=", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", "lodash": "4.17.4" } }, @@ -716,10 +975,10 @@ "dev": true, "requires": { "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-replace-supers": { @@ -729,10 +988,10 @@ "requires": { "babel-helper-optimise-call-expression": "6.24.1", "babel-messages": "6.23.0", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helpers": { @@ -740,8 +999,8 @@ "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", "requires": { - "babel-runtime": "6.23.0", - "babel-template": "6.25.0" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-istanbul": { @@ -754,14 +1013,14 @@ "async": "1.5.2", "escodegen": "1.8.1", "esprima": "2.7.3", - "handlebars": "4.0.10", - "js-yaml": "3.9.0", + "handlebars": "4.0.11", + "js-yaml": "3.10.0", "mkdirp": "0.5.1", "multi-glob": "1.0.1", "nopt": "3.0.6", "object-assign": "4.1.1", "once": "1.4.0", - "resolve": "1.3.3", + "resolve": "1.5.0", "source-map": "0.4.4", "supports-color": "3.1.2", "which": "1.2.14", @@ -804,6 +1063,15 @@ "has-flag": "1.0.0" } }, + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -829,7 +1097,7 @@ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-add-module-exports": { @@ -843,7 +1111,17 @@ "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-lodash": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/babel-plugin-lodash/-/babel-plugin-lodash-3.2.11.tgz", + "integrity": "sha1-Icj97J/hg176pzeHPjkCvdZtVwE=", + "dev": true, + "requires": { + "glob": "7.1.2", + "lodash": "4.17.4" } }, "babel-plugin-syntax-async-functions": { @@ -936,7 +1214,7 @@ "requires": { "babel-helper-remap-async-to-generator": "6.24.1", "babel-plugin-syntax-async-generators": "6.13.0", - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-async-to-generator": { @@ -947,7 +1225,7 @@ "requires": { "babel-helper-remap-async-to-generator": "6.24.1", "babel-plugin-syntax-async-functions": "6.13.0", - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-class-constructor-call": { @@ -957,8 +1235,8 @@ "dev": true, "requires": { "babel-plugin-syntax-class-constructor-call": "6.18.0", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-class-properties": { @@ -969,8 +1247,8 @@ "requires": { "babel-helper-function-name": "6.24.1", "babel-plugin-syntax-class-properties": "6.13.0", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-decorators": { @@ -981,9 +1259,9 @@ "requires": { "babel-helper-explode-class": "6.24.1", "babel-plugin-syntax-decorators": "6.13.0", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-do-expressions": { @@ -993,7 +1271,7 @@ "dev": true, "requires": { "babel-plugin-syntax-do-expressions": "6.13.0", - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-arrow-functions": { @@ -1001,7 +1279,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-block-scoped-functions": { @@ -1009,18 +1287,18 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-block-scoping": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz", - "integrity": "sha1-dsKV3DpHQbFmWt/TFnIV3P8ypXY=", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", "requires": { - "babel-runtime": "6.23.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", "lodash": "4.17.4" } }, @@ -1029,15 +1307,15 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", "requires": { - "babel-helper-define-map": "6.24.1", + "babel-helper-define-map": "6.26.0", "babel-helper-function-name": "6.24.1", "babel-helper-optimise-call-expression": "6.24.1", "babel-helper-replace-supers": "6.24.1", "babel-messages": "6.23.0", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-computed-properties": { @@ -1045,8 +1323,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", "requires": { - "babel-runtime": "6.23.0", - "babel-template": "6.25.0" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-destructuring": { @@ -1054,7 +1332,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-duplicate-keys": { @@ -1062,8 +1340,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-for-of": { @@ -1071,7 +1349,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-function-name": { @@ -1080,8 +1358,8 @@ "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", "requires": { "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-literals": { @@ -1089,7 +1367,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-modules-amd": { @@ -1097,20 +1375,20 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0" + "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz", - "integrity": "sha1-0+MQtA72ZKNmIiAAl8bUQCmPK/4=", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz", + "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=", "requires": { "babel-plugin-transform-strict-mode": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-modules-systemjs": { @@ -1119,8 +1397,8 @@ "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", "requires": { "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-modules-umd": { @@ -1129,8 +1407,8 @@ "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", "requires": { "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-object-super": { @@ -1139,7 +1417,7 @@ "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", "requires": { "babel-helper-replace-supers": "6.24.1", - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-parameters": { @@ -1149,10 +1427,10 @@ "requires": { "babel-helper-call-delegate": "6.24.1", "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-shorthand-properties": { @@ -1160,8 +1438,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-spread": { @@ -1169,7 +1447,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-sticky-regex": { @@ -1177,9 +1455,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", "requires": { - "babel-helper-regex": "6.24.1", - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-template-literals": { @@ -1187,7 +1465,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-typeof-symbol": { @@ -1195,7 +1473,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-unicode-regex": { @@ -1203,8 +1481,8 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", "requires": { - "babel-helper-regex": "6.24.1", - "babel-runtime": "6.23.0", + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", "regexpu-core": "2.0.0" } }, @@ -1216,7 +1494,7 @@ "requires": { "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", "babel-plugin-syntax-exponentiation-operator": "6.13.0", - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-export-extensions": { @@ -1226,7 +1504,7 @@ "dev": true, "requires": { "babel-plugin-syntax-export-extensions": "6.13.0", - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-flow-strip-types": { @@ -1235,7 +1513,7 @@ "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=", "requires": { "babel-plugin-syntax-flow": "6.18.0", - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-function-bind": { @@ -1245,17 +1523,17 @@ "dev": true, "requires": { "babel-plugin-syntax-function-bind": "6.13.0", - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-object-rest-spread": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.23.0.tgz", - "integrity": "sha1-h11ryb52HFiirj/u5dxIldjH+SE=", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", "dev": true, "requires": { "babel-plugin-syntax-object-rest-spread": "6.13.0", - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-react-display-name": { @@ -1263,7 +1541,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz", "integrity": "sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE=", "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-react-jsx": { @@ -1271,9 +1549,9 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", "integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=", "requires": { - "babel-helper-builder-react-jsx": "6.24.1", + "babel-helper-builder-react-jsx": "6.26.0", "babel-plugin-syntax-jsx": "6.18.0", - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-react-jsx-self": { @@ -1282,7 +1560,7 @@ "integrity": "sha1-322AqdomEqEh5t3XVYvL7PBuY24=", "requires": { "babel-plugin-syntax-jsx": "6.18.0", - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-react-jsx-source": { @@ -1291,15 +1569,15 @@ "integrity": "sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY=", "requires": { "babel-plugin-syntax-jsx": "6.18.0", - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-regenerator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz", - "integrity": "sha1-uNowWtQ8PJm0hI5P5AN7dw0jxBg=", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", "requires": { - "regenerator-transform": "0.9.11" + "regenerator-transform": "0.10.1" } }, "babel-plugin-transform-strict-mode": { @@ -1307,19 +1585,27 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-polyfill": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.23.0.tgz", - "integrity": "sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0=", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", "dev": true, "requires": { - "babel-runtime": "6.23.0", - "core-js": "2.4.1", + "babel-runtime": "6.26.0", + "core-js": "2.5.1", "regenerator-runtime": "0.10.5" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", + "dev": true + } } }, "babel-preset-es2015": { @@ -1330,7 +1616,7 @@ "babel-plugin-check-es2015-constants": "6.22.0", "babel-plugin-transform-es2015-arrow-functions": "6.22.0", "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoping": "6.24.1", + "babel-plugin-transform-es2015-block-scoping": "6.26.0", "babel-plugin-transform-es2015-classes": "6.24.1", "babel-plugin-transform-es2015-computed-properties": "6.24.1", "babel-plugin-transform-es2015-destructuring": "6.23.0", @@ -1339,7 +1625,7 @@ "babel-plugin-transform-es2015-function-name": "6.24.1", "babel-plugin-transform-es2015-literals": "6.22.0", "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", "babel-plugin-transform-es2015-modules-umd": "6.24.1", "babel-plugin-transform-es2015-object-super": "6.24.1", @@ -1350,7 +1636,7 @@ "babel-plugin-transform-es2015-template-literals": "6.22.0", "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", "babel-plugin-transform-es2015-unicode-regex": "6.24.1", - "babel-plugin-transform-regenerator": "6.24.1" + "babel-plugin-transform-regenerator": "6.26.0" } }, "babel-preset-flow": { @@ -1418,75 +1704,75 @@ "babel-plugin-transform-async-generator-functions": "6.24.1", "babel-plugin-transform-async-to-generator": "6.24.1", "babel-plugin-transform-exponentiation-operator": "6.24.1", - "babel-plugin-transform-object-rest-spread": "6.23.0" + "babel-plugin-transform-object-rest-spread": "6.26.0" } }, "babel-register": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.1.tgz", - "integrity": "sha1-fhDhOi9xBlvfrVoXh7pFvKbe118=", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", "requires": { - "babel-core": "6.25.0", - "babel-runtime": "6.23.0", - "core-js": "2.4.1", + "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.15" + "source-map-support": "0.4.18" } }, "babel-runtime": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", - "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.10.5" + "core-js": "2.5.1", + "regenerator-runtime": "0.11.0" } }, "babel-template": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.25.0.tgz", - "integrity": "sha1-ZlJBFmt8KqTGGdceGSlpVSsQwHE=", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", "requires": { - "babel-runtime": "6.23.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0", - "babylon": "6.17.4", + "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.25.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.25.0.tgz", - "integrity": "sha1-IldJfi/NGbie3BPEyROB+VEklvE=", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", "requires": { - "babel-code-frame": "6.22.0", + "babel-code-frame": "6.26.0", "babel-messages": "6.23.0", - "babel-runtime": "6.23.0", - "babel-types": "6.25.0", - "babylon": "6.17.4", - "debug": "2.6.8", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "debug": "2.6.9", "globals": "9.18.0", "invariant": "2.2.2", "lodash": "4.17.4" } }, "babel-types": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.25.0.tgz", - "integrity": "sha1-cK+ySNVmDl0Y+BHZHIMDtUE0oY4=", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", "requires": { - "babel-runtime": "6.23.0", + "babel-runtime": "6.26.0", "esutils": "2.0.2", "lodash": "4.17.4", "to-fast-properties": "1.0.3" } }, "babylon": { - "version": "6.17.4", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.17.4.tgz", - "integrity": "sha512-kChlV+0SXkjE0vUn9OZ7pBMWRFd8uq3mZe8x1K6jhuNcAFAtEnjchFAqB+dYEXKyd+JpT6eppRR78QAr5gTsUw==" + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" }, "backo2": { "version": "1.0.2", @@ -1499,6 +1785,12 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, + "base-64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", + "integrity": "sha1-eAqZyE59YAJgNhURxId2E78k9rs=", + "dev": true + }, "base64-arraybuffer": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", @@ -1522,9 +1814,12 @@ "integrity": "sha1-6sFuA+oUOO/5Qj1puqNiYu0fcLs=" }, "basic-auth": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz", - "integrity": "sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz", + "integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=", + "requires": { + "safe-buffer": "5.1.1" + } }, "batch": { "version": "0.5.3", @@ -1552,6 +1847,15 @@ "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", "dev": true }, + "berkeleys-redux-utils": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/berkeleys-redux-utils/-/berkeleys-redux-utils-3.2.0.tgz", + "integrity": "sha512-w6MZvum7TuVLxHoBqidlXtwdp325hEfTUx128tytV1sitHt75LnitR9evgWecV6O9IcKItx6lDNQiQkr177dBQ==", + "requires": { + "babel-runtime": "6.26.0", + "invariant": "2.2.2" + } + }, "better-assert": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", @@ -1562,15 +1866,15 @@ } }, "big.js": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.1.3.tgz", - "integrity": "sha1-TK2iGTZS6zyp7I5VyQFWacmAaXg=", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", "dev": true }, "binary-extensions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.8.0.tgz", - "integrity": "sha1-SOyNFt9Dd+rl+liEaCSAr02Vx3Q=", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz", + "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=", "dev": true }, "bl": { @@ -1588,43 +1892,33 @@ "dev": true }, "bluebird": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", - "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=" + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" }, "body-parser": { - "version": "1.17.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz", - "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=", + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", "requires": { - "bytes": "2.4.0", - "content-type": "1.0.2", - "debug": "2.6.7", - "depd": "1.1.0", - "http-errors": "1.6.1", - "iconv-lite": "0.4.15", + "bytes": "3.0.0", + "content-type": "1.0.4", + "debug": "2.6.9", + "depd": "1.1.1", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", "on-finished": "2.3.0", - "qs": "6.4.0", - "raw-body": "2.2.0", + "qs": "6.5.1", + "raw-body": "2.3.2", "type-is": "1.6.15" - }, - "dependencies": { - "debug": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", - "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", - "requires": { - "ms": "2.0.0" - } - } } }, "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", "requires": { - "hoek": "2.16.3" + "hoek": "4.2.0" } }, "bootstrap": { @@ -1642,9 +1936,9 @@ } }, "bowser": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.7.0.tgz", - "integrity": "sha1-Fp3kAYcR+ZQkK/+agAnneh814AM=" + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.8.1.tgz", + "integrity": "sha512-NMPaR8ILtdLSWzxQtEs16XbxMcY8ohWGQ5V+TZSJS3fNUt/PBAGkF6YWO9B/4qWE23bK3o0moQKq8UyFEosYkA==" }, "boxen": { "version": "0.3.1", @@ -1680,9 +1974,9 @@ } }, "browser-sync": { - "version": "2.18.12", - "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.18.12.tgz", - "integrity": "sha1-u6oKF6lh4rXwqOdg5pUCcYZmR3k=", + "version": "2.18.13", + "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.18.13.tgz", + "integrity": "sha512-qhdrmgshVGwweogT/bdOKkZDxVxqiF4+9mibaDeAxvDBeoUtdgABk5x7YQ1KCcLRchAfv8AVtp9NuITl5CTNqg==", "dev": true, "requires": { "browser-sync-client": "2.5.1", @@ -1697,7 +1991,7 @@ "fs-extra": "3.0.1", "http-proxy": "1.15.2", "immutable": "3.8.1", - "localtunnel": "1.8.2", + "localtunnel": "1.8.3", "micromatch": "2.3.11", "opn": "4.0.2", "portscanner": "2.1.1", @@ -1724,46 +2018,50 @@ "wrap-ansi": "2.1.0" } }, - "connect": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.5.0.tgz", - "integrity": "sha1-s1dSWgtMH1BZnNmD4dnv7qlncZg=", - "dev": true, - "requires": { - "debug": "2.2.0", - "finalhandler": "0.5.0", - "parseurl": "1.3.1", - "utils-merge": "1.0.0" - } - }, "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.4.tgz", + "integrity": "sha1-dYaps8OXQcAoKuM0RcTorHRzT+A=", "dev": true, "requires": { - "ms": "0.7.1" + "ms": "0.7.3" + }, + "dependencies": { + "ms": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz", + "integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8=", + "dev": true + } } }, - "finalhandler": { + "fresh": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.5.0.tgz", - "integrity": "sha1-6VCKvs6bbbqHGmlCodeRG5GRGsc=", - "dev": true, - "requires": { - "debug": "2.2.0", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "statuses": "1.3.1", - "unpipe": "1.0.0" - } + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz", + "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44=", + "dev": true + }, + "mime": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", + "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=", + "dev": true }, "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-1.0.0.tgz", + "integrity": "sha1-Wa3NIu3FQ/e1OBhi0xOHsfS8lHM=", "dev": true }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "1.0.0" + } + }, "qs": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.1.tgz", @@ -1783,43 +2081,18 @@ "dev": true, "requires": { "debug": "2.6.4", - "depd": "1.1.0", + "depd": "1.1.1", "destroy": "1.0.4", "encodeurl": "1.0.1", "escape-html": "1.0.3", - "etag": "1.8.0", + "etag": "1.8.1", "fresh": "0.5.0", - "http-errors": "1.6.1", + "http-errors": "1.6.2", "mime": "1.3.4", "ms": "1.0.0", "on-finished": "2.3.0", "range-parser": "1.2.0", "statuses": "1.3.1" - }, - "dependencies": { - "debug": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.4.tgz", - "integrity": "sha1-dYaps8OXQcAoKuM0RcTorHRzT+A=", - "dev": true, - "requires": { - "ms": "0.7.3" - }, - "dependencies": { - "ms": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz", - "integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8=", - "dev": true - } - } - }, - "ms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-1.0.0.tgz", - "integrity": "sha1-Wa3NIu3FQ/e1OBhi0xOHsfS8lHM=", - "dev": true - } } }, "serve-static": { @@ -1830,10 +2103,16 @@ "requires": { "encodeurl": "1.0.1", "escape-html": "1.0.3", - "parseurl": "1.3.1", + "parseurl": "1.3.2", "send": "0.15.2" } }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + }, "ua-parser-js": { "version": "0.7.12", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.12.tgz", @@ -1885,7 +2164,7 @@ "integrity": "sha1-7BrWmknC4tS2RbGLHAbCmz2a+Os=", "dev": true, "requires": { - "etag": "1.8.0", + "etag": "1.8.1", "fresh": "0.3.0" }, "dependencies": { @@ -1904,7 +2183,7 @@ "dev": true, "requires": { "async-each-series": "0.1.1", - "connect-history-api-fallback": "1.3.0", + "connect-history-api-fallback": "1.4.0", "immutable": "3.8.1", "server-destroy": "1.0.1", "stream-throttle": "0.1.3", @@ -2007,9 +2286,9 @@ "dev": true }, "bytes": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", - "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, "cachedir": { "version": "1.1.1", @@ -2076,9 +2355,9 @@ "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" }, "caniuse-db": { - "version": "1.0.30000700", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000700.tgz", - "integrity": "sha1-l8/Eg4Ze6oV33Ho2dJKbmr9VMJU=" + "version": "1.0.30000756", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000756.tgz", + "integrity": "sha1-6TimuZFjDzDSJj3TRYvrZdNiJos=" }, "canonical-json": { "version": "0.0.4", @@ -2170,7 +2449,7 @@ "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", "dev": true, "requires": { - "anymatch": "1.3.0", + "anymatch": "1.3.2", "async-each": "1.0.1", "fsevents": "1.1.2", "glob-parent": "2.0.0", @@ -2191,15 +2470,15 @@ } }, "ci-info": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.0.0.tgz", - "integrity": "sha1-3FKF8rTiUYIWg2gcOBwziPRuxTQ=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.1.tgz", + "integrity": "sha512-vHDDF/bP9RYpTWtUhpJRhCFdvvp3iDWvEbuDbWgvjUrNGV1MXJrE0MPcwGtEled04m61iwdBLUIHZtDgzWS4ZQ==", "dev": true }, "circular-json": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.1.tgz", - "integrity": "sha1-vos2rvzN6LPKeqLWr8B6NyQsDS0=", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", "dev": true }, "classnames": { @@ -2208,9 +2487,9 @@ "integrity": "sha1-+zgB1FNGdknvNgPH1hoCvRKb3m0=" }, "clean-css": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.27.tgz", - "integrity": "sha1-re91sxwWD/pdcvTeZ5ZuJmDBolU=", + "version": "3.4.28", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz", + "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=", "requires": { "commander": "2.8.1", "source-map": "0.4.4" @@ -2243,6 +2522,12 @@ "glob": "7.1.2" } }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "dev": true + }, "cli-cursor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", @@ -2288,17 +2573,17 @@ } }, "cli-width": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", - "integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" }, "clite": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/clite/-/clite-0.3.0.tgz", "integrity": "sha1-5/y8jMW9Pn+LhO1I2xLpR0zHNEE=", "requires": { - "abbrev": "1.1.0", - "debug": "2.6.8", + "abbrev": "1.1.1", + "debug": "2.6.9", "es6-promise": "3.2.1", "lodash.defaults": "4.2.0", "lodash.defaultsdeep": "4.6.0", @@ -2334,6 +2619,14 @@ "xdg-basedir": "2.0.0" } }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "requires": { + "lcid": "1.0.0" + } + }, "update-notifier": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-0.6.3.tgz", @@ -2452,6 +2745,21 @@ "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.15.2.tgz", "integrity": "sha1-WLPccyxtENeq6Ab0x83VapuH/o8=" }, + "color-convert": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", + "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, "colors": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", @@ -2534,7 +2842,7 @@ "ansi-escapes": "1.4.0", "chalk": "1.1.3", "cli-cursor": "1.0.2", - "cli-width": "2.1.0", + "cli-width": "2.2.0", "external-editor": "1.1.1", "figures": "1.7.0", "lodash": "4.17.2", @@ -2581,7 +2889,7 @@ "dev": true, "requires": { "glob": "7.1.1", - "interpret": "1.0.3", + "interpret": "1.0.4", "rechoir": "0.6.2" } }, @@ -2605,9 +2913,10 @@ "dev": true }, "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", + "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=", + "dev": true }, "component-inherit": { "version": "0.0.3", @@ -2616,32 +2925,25 @@ "dev": true }, "compressible": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.10.tgz", - "integrity": "sha1-/tocf3YXkScyspv4zyYlKiC57s0=", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.12.tgz", + "integrity": "sha1-xZpcmdt2dn6YdlAOJx72OzSTvWY=", "requires": { - "mime-db": "1.27.0" + "mime-db": "1.30.0" } }, "compression": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.0.tgz", - "integrity": "sha1-AwyfGY8WQ6BX13anOOki2kNzAS0=", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.1.tgz", + "integrity": "sha1-7/JgPvwuIs+G810uuTWJ+YdTc9s=", "requires": { - "accepts": "1.3.3", - "bytes": "2.5.0", - "compressible": "2.0.10", - "debug": "2.6.8", + "accepts": "1.3.4", + "bytes": "3.0.0", + "compressible": "2.0.12", + "debug": "2.6.9", "on-headers": "1.0.1", "safe-buffer": "5.1.1", - "vary": "1.1.1" - }, - "dependencies": { - "bytes": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.5.0.tgz", - "integrity": "sha1-TJQj6i0lLCcMQbK97+/5u2tiwGo=" - } + "vary": "1.1.2" } }, "concat-map": { @@ -2666,7 +2968,7 @@ "integrity": "sha1-9Vs74q60dgGxCi1SWcz7cP0vHdY=", "dev": true, "requires": { - "source-map": "0.5.6" + "source-map": "0.5.7" } }, "configstore": { @@ -2692,23 +2994,56 @@ } }, "connect": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.2.tgz", - "integrity": "sha1-aU6NIGgb/kkCgsiriGvpjwn0L+c=", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.5.0.tgz", + "integrity": "sha1-s1dSWgtMH1BZnNmD4dnv7qlncZg=", + "dev": true, "requires": { - "debug": "2.6.7", - "finalhandler": "1.0.3", - "parseurl": "1.3.1", + "debug": "2.2.0", + "finalhandler": "0.5.0", + "parseurl": "1.3.2", "utils-merge": "1.0.0" }, "dependencies": { "debug": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", - "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, "requires": { - "ms": "2.0.0" + "ms": "0.7.1" } + }, + "finalhandler": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.5.0.tgz", + "integrity": "sha1-6VCKvs6bbbqHGmlCodeRG5GRGsc=", + "dev": true, + "requires": { + "debug": "2.2.0", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "statuses": "1.3.1", + "unpipe": "1.0.0" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + }, + "utils-merge": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", + "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=", + "dev": true } } }, @@ -2718,9 +3053,9 @@ "integrity": "sha1-2GMPJtlaf4UfmVax6MxnMvO2qjA=" }, "connect-history-api-fallback": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.3.0.tgz", - "integrity": "sha1-5R0X+PDvDbkKZP20feMFFVbp8Wk=", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.4.0.tgz", + "integrity": "sha1-PbJPlz9LkjsOgvYZzg3wJBHKYj0=", "dev": true }, "connect-mongo": { @@ -2728,8 +3063,8 @@ "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-1.3.2.tgz", "integrity": "sha1-fL9Y3/8mdg5eAOAX0KhbS8kLnTc=", "requires": { - "bluebird": "3.5.0", - "mongodb": "2.2.30" + "bluebird": "3.5.1", + "mongodb": "2.2.33" } }, "console-browserify": { @@ -2779,16 +3114,16 @@ } }, "content-type": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz", - "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0=" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, "continuation-local-storage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.0.tgz", "integrity": "sha1-4Z/Da1lwkKXU5KOy6j68XilpSiQ=", "requires": { - "async-listener": "0.6.7", + "async-listener": "0.6.8", "emitter-listener": "1.0.1" } }, @@ -2822,15 +3157,10 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, - "cookiejar": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.1.tgz", - "integrity": "sha1-Qa1XsbVVlR7BcUEqgZQrHoIA00o=" - }, "core-js": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", - "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=" + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", + "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=" }, "core-util-is": { "version": "1.0.2", @@ -2838,18 +3168,18 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cors": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.3.tgz", - "integrity": "sha1-TPeOHSMymnSWsvwiJbd8pbteuAI=", + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", + "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", "requires": { "object-assign": "4.1.1", - "vary": "1.1.1" + "vary": "1.1.2" } }, "coveralls": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-2.13.1.tgz", - "integrity": "sha1-1wu5rMGDXsTwY/+drFQjwXsR8Xg=", + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-2.13.3.tgz", + "integrity": "sha512-iiAmn+l1XqRwNLXhW8Rs5qHZRFMYp9ZIPjEOVRpC/c4so6Y/f4/lFi0FfR5B9cCqgyhkJ5cZmbvcVRfP8MHchw==", "dev": true, "requires": { "js-yaml": "3.6.1", @@ -2859,6 +3189,27 @@ "request": "2.79.0" }, "dependencies": { + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, "caseless": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", @@ -2871,12 +3222,32 @@ "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", "dev": true }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, "esprima": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", "dev": true }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "dev": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + } + }, "har-validator": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", @@ -2885,10 +3256,39 @@ "requires": { "chalk": "1.1.3", "commander": "2.11.0", - "is-my-json-valid": "2.16.0", + "is-my-json-valid": "2.16.1", "pinkie-promise": "2.0.1" } }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, "js-yaml": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz", @@ -2930,15 +3330,24 @@ "is-typedarray": "1.0.0", "isstream": "0.1.2", "json-stringify-safe": "5.0.1", - "mime-types": "2.1.15", + "mime-types": "2.1.17", "oauth-sign": "0.8.2", "qs": "6.3.2", "stringstream": "0.0.5", - "tough-cookie": "2.3.2", + "tough-cookie": "2.3.3", "tunnel-agent": "0.4.3", "uuid": "3.1.0" } }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, "tunnel-agent": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", @@ -2961,26 +3370,46 @@ } }, "create-react-class": { - "version": "15.6.0", - "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.0.tgz", - "integrity": "sha1-q0SEl8JlZuHilBPogyB9V8/nvtQ=", + "version": "15.6.2", + "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.2.tgz", + "integrity": "sha1-zx7RXxKq1/FO9fLf4F5sQvke8Co=", "requires": { - "fbjs": "0.8.12", + "fbjs": "0.8.16", "loose-envify": "1.3.1", "object-assign": "4.1.1" } }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, "crypt": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" }, "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", "requires": { - "boom": "2.10.1" + "boom": "5.2.0" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "requires": { + "hoek": "4.2.0" + } + } } }, "crypto-browserify": { @@ -2988,6 +3417,12 @@ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-1.0.9.tgz", "integrity": "sha1-zFRJaF37hesRyYKKzHy4erW7/MA=" }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "dev": true + }, "csrf": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/csrf/-/csrf-3.0.6.tgz", @@ -3035,7 +3470,7 @@ "requires": { "inherits": "2.0.3", "setprototypeof": "1.0.2", - "statuses": "1.3.1" + "statuses": "1.4.0" } }, "setprototypeof": { @@ -3092,7 +3527,7 @@ "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "requires": { - "es5-ext": "0.10.24" + "es5-ext": "0.10.35" } }, "d3": { @@ -3106,13 +3541,6 @@ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "requires": { "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } } }, "dasherize": { @@ -3131,34 +3559,38 @@ "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=" }, "dateformat": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz", - "integrity": "sha1-J0Pjq7XD/CRi5SfcpEXgTp9N7hc=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", + "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=", "dev": true }, "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "requires": { "ms": "2.0.0" } }, "debug-fabulous": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-0.1.0.tgz", - "integrity": "sha1-rQ6gel1RkyT7VYQqjzTuWcf4/2w=", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-0.2.1.tgz", + "integrity": "sha512-u0TV6HcfLsZ03xLBhdhSViQMldaiQ2o+8/nSILaXkuNSWvxkx66vYJUAam0Eu7gAilJRX/69J4kKdqajQPaPyw==", "dev": true, "requires": { - "debug": "2.6.8", - "object-assign": "4.1.0" + "debug": "3.1.0", + "memoizee": "0.4.11", + "object-assign": "4.1.1" }, "dependencies": { - "object-assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", - "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", - "dev": true + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } } } }, @@ -3269,9 +3701,9 @@ "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=" }, "depd": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz", - "integrity": "sha1-4b2Cxqq2ztlluXuIsX7T5SjKGMM=" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" }, "deprecated": { "version": "0.0.1", @@ -3429,12 +3861,18 @@ "readable-stream": "2.2.7" } }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, "duplexify": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.0.tgz", - "integrity": "sha1-GqdzAC4VeEV+nZ1KULDMquvL1gQ=", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.1.tgz", + "integrity": "sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ==", "requires": { - "end-of-stream": "1.0.0", + "end-of-stream": "1.4.0", "inherits": "2.0.3", "readable-stream": "2.2.7", "stream-shift": "1.0.0" @@ -3500,9 +3938,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "ejs": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.6.tgz", - "integrity": "sha1-R5Y2v6P+Ox3r1SCH8KyyBLTxnIg=" + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.7.tgz", + "integrity": "sha1-zIcsFoiArjxxiXYv1f/ACJbJUYo=" }, "emitter-listener": { "version": "1.0.1", @@ -3530,7 +3968,7 @@ "resolved": "https://registry.npmjs.org/emmet/-/emmet-1.6.3.tgz", "integrity": "sha1-/hPXdO7jMv5L9sCsjLLWhhbqUME=", "requires": { - "caniuse-db": "1.0.30000700" + "caniuse-db": "1.0.30000756" } }, "emmet-codemirror": { @@ -3557,25 +3995,15 @@ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", "requires": { - "iconv-lite": "0.4.15" + "iconv-lite": "0.4.19" } }, "end-of-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz", - "integrity": "sha1-1FlucCc0qT5A6a+GQxnqvZn/Lw4=", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", + "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", "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=", - "requires": { - "wrappy": "1.0.2" - } - } + "once": "1.4.0" } }, "engine.io": { @@ -3592,6 +4020,16 @@ "ws": "1.1.1" }, "dependencies": { + "accepts": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", + "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", + "dev": true, + "requires": { + "mime-types": "2.1.17", + "negotiator": "0.6.1" + } + }, "debug": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", @@ -3629,6 +4067,12 @@ "yeast": "0.1.2" }, "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, "debug": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", @@ -3728,18 +4172,19 @@ "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.0.tgz", "integrity": "sha1-6rpkyl1UKjEayUX1gt78M2Fl2fQ=", "requires": { - "accepts": "1.3.3", + "accepts": "1.3.4", "escape-html": "1.0.3" } }, "es-abstract": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.7.0.tgz", - "integrity": "sha1-363ndOAb/Nl/lhgCmMRJyGI/uUw=", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.9.0.tgz", + "integrity": "sha512-kk3IJoKo7A3pWJc0OV8yZ/VEX2oSUytfekrJiqoxBlKJMFAJVJVpGdHClCCTdv+Fn2zHfpDHHIelMFhZVfef3Q==", "dev": true, "requires": { "es-to-primitive": "1.1.1", - "function-bind": "1.1.0", + "function-bind": "1.1.1", + "has": "1.0.1", "is-callable": "1.1.3", "is-regex": "1.0.4" } @@ -3756,21 +4201,21 @@ } }, "es5-ext": { - "version": "0.10.24", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.24.tgz", - "integrity": "sha1-pVh3yZJLwMjZvTwsvhdJWsFwmxQ=", + "version": "0.10.35", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.35.tgz", + "integrity": "sha1-GO6FjOajxFx9eekcFfzKnsVoSU8=", "requires": { - "es6-iterator": "2.0.1", + "es6-iterator": "2.0.3", "es6-symbol": "3.1.1" } }, "es6-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", - "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", "requires": { "d": "1.0.0", - "es5-ext": "0.10.24", + "es5-ext": "0.10.35", "es6-symbol": "3.1.1" } }, @@ -3780,8 +4225,8 @@ "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", "requires": { "d": "1.0.0", - "es5-ext": "0.10.24", - "es6-iterator": "2.0.1", + "es5-ext": "0.10.35", + "es6-iterator": "2.0.3", "es6-set": "0.1.5", "es6-symbol": "3.1.1", "event-emitter": "0.3.5" @@ -3798,8 +4243,8 @@ "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", "requires": { "d": "1.0.0", - "es5-ext": "0.10.24", - "es6-iterator": "2.0.1", + "es5-ext": "0.10.35", + "es6-iterator": "2.0.3", "es6-symbol": "3.1.1", "event-emitter": "0.3.5" } @@ -3810,7 +4255,7 @@ "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", "requires": { "d": "1.0.0", - "es5-ext": "0.10.24" + "es5-ext": "0.10.35" } }, "es6-weak-map": { @@ -3820,8 +4265,8 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.24", - "es6-iterator": "2.0.1", + "es5-ext": "0.10.35", + "es6-iterator": "2.0.3", "es6-symbol": "3.1.1" } }, @@ -3885,120 +4330,245 @@ } }, "eslint": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.10.0.tgz", + "integrity": "sha512-MMVl8P/dYUFZEvolL8PYt7qc5LNdS2lwheq9BYa5Y07FblhcZqFyaUqlS8TW5QITGex21tV4Lk0a3fK8lsJIkA==", "dev": true, "requires": { - "babel-code-frame": "6.22.0", - "chalk": "1.1.3", + "ajv": "5.3.0", + "babel-code-frame": "6.26.0", + "chalk": "2.3.0", "concat-stream": "1.6.0", - "debug": "2.6.8", + "cross-spawn": "5.1.0", + "debug": "3.1.0", "doctrine": "2.0.0", - "escope": "3.6.0", - "espree": "3.4.3", + "eslint-scope": "3.7.1", + "espree": "3.5.1", "esquery": "1.0.0", "estraverse": "4.2.0", "esutils": "2.0.2", "file-entry-cache": "2.0.0", + "functional-red-black-tree": "1.0.1", "glob": "7.1.2", "globals": "9.18.0", - "ignore": "3.3.3", + "ignore": "3.3.7", "imurmurhash": "0.1.4", - "inquirer": "0.12.0", - "is-my-json-valid": "2.16.0", + "inquirer": "3.3.0", "is-resolvable": "1.0.0", - "js-yaml": "3.9.0", + "js-yaml": "3.10.0", "json-stable-stringify": "1.0.1", "levn": "0.3.0", "lodash": "4.17.4", + "minimatch": "3.0.4", "mkdirp": "0.5.1", "natural-compare": "1.4.0", "optionator": "0.8.2", "path-is-inside": "1.0.2", - "pluralize": "1.2.1", - "progress": "1.1.8", + "pluralize": "7.0.0", + "progress": "2.0.0", "require-uncached": "1.0.3", - "shelljs": "0.7.8", - "strip-bom": "3.0.0", + "semver": "5.4.1", + "strip-ansi": "4.0.0", "strip-json-comments": "2.0.1", - "table": "3.8.3", - "text-table": "0.2.0", - "user-home": "2.0.0" + "table": "4.0.2", + "text-table": "0.2.0" }, "dependencies": { - "inquirer": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "ansi-escapes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", + "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "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": { - "ansi-escapes": "1.4.0", - "ansi-regex": "2.1.1", - "chalk": "1.1.3", - "cli-cursor": "1.0.2", - "cli-width": "2.1.0", - "figures": "1.7.0", + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "2.0.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "external-editor": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.5.tgz", + "integrity": "sha512-Msjo64WT5W+NhOpQXh0nOHm+n0RfU1QUwDnKYvJ8dEJ8zlwLrqXNTv5mSUTJpepf41PDJGyhueTw2vNZW+Fr/w==", + "dev": true, + "requires": { + "iconv-lite": "0.4.19", + "jschardet": "1.6.0", + "tmp": "0.0.33" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, + "requires": { + "ansi-escapes": "3.0.0", + "chalk": "2.3.0", + "cli-cursor": "2.1.0", + "cli-width": "2.2.0", + "external-editor": "2.0.5", + "figures": "2.0.0", "lodash": "4.17.4", - "readline2": "1.0.1", - "run-async": "0.1.0", - "rx-lite": "3.1.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rx-lite": "4.0.8", + "rx-lite-aggregates": "4.0.8", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", "through": "2.3.8" } }, - "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", - "dev": true, - "requires": { - "once": "1.4.0" - } - }, - "shelljs": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", - "dev": true, - "requires": { - "glob": "7.1.2", - "interpret": "1.0.3", - "rechoir": "0.6.2" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "2.0.1", + "signal-exit": "3.0.2" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, - "user-home": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { - "os-homedir": "1.0.2" + "has-flag": "2.0.0" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2" } } } }, + "eslint-config-freecodecamp": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/eslint-config-freecodecamp/-/eslint-config-freecodecamp-1.1.1.tgz", + "integrity": "sha512-gTse8e765b42K2THtK5d6oNsssqh4aWJQnzuUdwGPy4i+Vz5m6QrZy0Ti5AWE1mPpuKeqIP1bTULhId6czy6ew==", + "dev": true, + "requires": { + "babel-eslint": "8.0.1", + "eslint": "4.10.0", + "eslint-plugin-import": "2.8.0", + "eslint-plugin-prefer-object-spread": "1.2.1", + "eslint-plugin-react": "7.4.0" + } + }, "eslint-import-resolver-node": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz", "integrity": "sha512-yUtXS15gIcij68NmXmP9Ni77AQuCN0itXbCc/jWd8C6/yKZaSNXicpC8cgvjnxVdmfsosIXrjpzFq7GcDryb6A==", "dev": true, "requires": { - "debug": "2.6.8", - "resolve": "1.3.3" + "debug": "2.6.9", + "resolve": "1.5.0" } }, "eslint-module-utils": { @@ -4007,19 +4577,19 @@ "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", "dev": true, "requires": { - "debug": "2.6.8", + "debug": "2.6.9", "pkg-dir": "1.0.0" } }, "eslint-plugin-import": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz", - "integrity": "sha512-HGYmpU9f/zJaQiKNQOVfHUh2oLWW3STBrCgH0sHTX1xtsxYlH1zjLh8FlQGEIdZSdTbUMaV36WaZ6ImXkenGxQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz", + "integrity": "sha512-Rf7dfKJxZ16QuTgVv1OYNxkZcsu/hULFnC+e+w0Gzi6jMC3guQoWQgxYxc54IDRinlb6/0v5z/PxxIKmVctN+g==", "dev": true, "requires": { "builtin-modules": "1.1.1", "contains-path": "0.1.0", - "debug": "2.6.8", + "debug": "2.6.9", "doctrine": "1.5.0", "eslint-import-resolver-node": "0.3.1", "eslint-module-utils": "2.1.1", @@ -4105,52 +4675,49 @@ "dev": true }, "eslint-plugin-react": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz", - "integrity": "sha1-xUNb6wZ3ThLH2y9qut3L+QDNP3g=", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.4.0.tgz", + "integrity": "sha512-tvjU9u3VqmW2vVuYnE8Qptq+6ji4JltjOjJ9u7VAOxVYkUkyBZWRvNYKbDv5fN+L6wiA+4we9+qQahZ0m63XEA==", "dev": true, "requires": { - "array.prototype.find": "2.0.4", - "doctrine": "1.5.0", + "doctrine": "2.0.0", "has": "1.0.1", - "jsx-ast-utils": "1.4.1", - "object.assign": "4.0.4" - }, - "dependencies": { - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" - } - } + "jsx-ast-utils": "2.0.1", + "prop-types": "15.6.0" + } + }, + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true, + "requires": { + "esrecurse": "4.2.0", + "estraverse": "4.2.0" } }, "espree": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.4.3.tgz", - "integrity": "sha1-KRC1zNSc6JPC//+qtP2LOjG4I3Q=", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.1.tgz", + "integrity": "sha1-DJiLirRttTEAoZVK5LqZXd0n2H4=", "dev": true, "requires": { - "acorn": "5.1.1", + "acorn": "5.2.1", "acorn-jsx": "3.0.1" }, "dependencies": { "acorn": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.1.tgz", - "integrity": "sha512-vOk6uEMctu0vQrvuSqFdJyqj1Q0S5VTDL79qtjo+DhRr+1mmaD+tluFSCZqhvi/JUhXSzoZN2BhtstaPEeE8cw==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", "dev": true } } }, "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" }, "esquery": { "version": "1.0.0", @@ -4182,9 +4749,9 @@ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" }, "etag": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.0.tgz", - "integrity": "sha1-b2Ma7zNtbEY2K1F2QETOIWvjwFE=" + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, "event-emitter": { "version": "0.3.5", @@ -4192,7 +4759,7 @@ "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", "requires": { "d": "1.0.0", - "es5-ext": "0.10.24" + "es5-ext": "0.10.35" } }, "event-stream": { @@ -4243,6 +4810,20 @@ "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -4286,47 +4867,51 @@ "integrity": "sha1-UnNWeN4YUwiQ2Ne5XwrGNkCVgJQ=" }, "express": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.15.3.tgz", - "integrity": "sha1-urZdDwOqgMNYQIly/HAPkWlEtmI=", + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", + "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", "requires": { - "accepts": "1.3.3", + "accepts": "1.3.4", "array-flatten": "1.1.1", + "body-parser": "1.18.2", "content-disposition": "0.5.2", - "content-type": "1.0.2", + "content-type": "1.0.4", "cookie": "0.3.1", "cookie-signature": "1.0.6", - "debug": "2.6.7", - "depd": "1.1.0", + "debug": "2.6.9", + "depd": "1.1.1", "encodeurl": "1.0.1", "escape-html": "1.0.3", - "etag": "1.8.0", - "finalhandler": "1.0.3", - "fresh": "0.5.0", + "etag": "1.8.1", + "finalhandler": "1.1.0", + "fresh": "0.5.2", "merge-descriptors": "1.0.1", "methods": "1.1.2", "on-finished": "2.3.0", - "parseurl": "1.3.1", + "parseurl": "1.3.2", "path-to-regexp": "0.1.7", - "proxy-addr": "1.1.4", - "qs": "6.4.0", + "proxy-addr": "2.0.2", + "qs": "6.5.1", "range-parser": "1.2.0", - "send": "0.15.3", - "serve-static": "1.12.3", - "setprototypeof": "1.0.3", + "safe-buffer": "5.1.1", + "send": "0.16.1", + "serve-static": "1.13.1", + "setprototypeof": "1.1.0", "statuses": "1.3.1", "type-is": "1.6.15", - "utils-merge": "1.0.0", - "vary": "1.1.1" + "utils-merge": "1.0.1", + "vary": "1.1.2" }, "dependencies": { - "debug": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", - "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", - "requires": { - "ms": "2.0.0" - } + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" } } }, @@ -4339,27 +4924,27 @@ } }, "express-session": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.15.3.tgz", - "integrity": "sha1-21RfBDWnsbIorgLagZf2UUFzXGc=", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.15.6.tgz", + "integrity": "sha512-r0nrHTCYtAMrFwZ0kBzZEXa1vtPVrw0dKvGSrKP4dahwBQ1BJpF2/y1Pp4sCD/0kvxV4zZeclyvfmw0B4RMJQA==", "requires": { "cookie": "0.3.1", "cookie-signature": "1.0.6", "crc": "3.4.4", - "debug": "2.6.7", - "depd": "1.1.0", + "debug": "2.6.9", + "depd": "1.1.1", "on-headers": "1.0.1", - "parseurl": "1.3.1", - "uid-safe": "2.1.4", - "utils-merge": "1.0.0" + "parseurl": "1.3.2", + "uid-safe": "2.1.5", + "utils-merge": "1.0.1" }, "dependencies": { - "debug": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", - "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", "requires": { - "ms": "2.0.0" + "random-bytes": "1.0.0" } } } @@ -4369,7 +4954,7 @@ "resolved": "https://registry.npmjs.org/express-state/-/express-state-1.4.0.tgz", "integrity": "sha1-OuEAEyrhH9/vg2/hkMq3unKdIn0=", "requires": { - "serialize-javascript": "1.3.0" + "serialize-javascript": "1.4.0" } }, "express-validator": { @@ -4377,9 +4962,9 @@ "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-3.2.1.tgz", "integrity": "sha1-RWA+fu5pMYXCGY+969QUkl/9NSQ=", "requires": { - "@types/bluebird": "3.5.8", - "@types/express": "4.0.36", - "bluebird": "3.5.0", + "@types/bluebird": "3.5.18", + "@types/express": "4.0.39", + "bluebird": "3.5.1", "lodash": "4.17.4", "validator": "6.2.1" }, @@ -4417,9 +5002,9 @@ } }, "extsprintf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", - "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, "eyes": { "version": "0.1.8", @@ -4436,6 +5021,21 @@ "time-stamp": "1.1.0" } }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" + }, + "fast-json-patch": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-1.1.8.tgz", + "integrity": "sha1-jbWMnRLD/5wjRW7oEswp+scit3I=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", @@ -4448,9 +5048,9 @@ "integrity": "sha1-69QmZv0Y/k8rpPDSlQZfP4XK3pY=" }, "fbjs": { - "version": "0.8.12", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.12.tgz", - "integrity": "sha1-ELXZL3bUVXX9Y6IX1OoCvqL47QQ=", + "version": "0.8.16", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz", + "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=", "requires": { "core-js": "1.2.7", "isomorphic-fetch": "2.2.1", @@ -4458,7 +5058,7 @@ "object-assign": "4.1.1", "promise": "7.3.1", "setimmediate": "1.0.5", - "ua-parser-js": "0.7.13" + "ua-parser-js": "0.7.17" }, "dependencies": { "asap": { @@ -4486,7 +5086,7 @@ "resolved": "https://registry.npmjs.org/fetchr/-/fetchr-0.5.37.tgz", "integrity": "sha1-SE3un0chWifV8ZuWFlviTgJI3mI=", "requires": { - "debug": "2.6.8", + "debug": "2.6.9", "es6-promise": "4.1.1", "fumble": "0.1.3", "lodash": "4.17.4", @@ -4516,7 +5116,7 @@ "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "dev": true, "requires": { - "flat-cache": "1.2.2", + "flat-cache": "1.3.0", "object-assign": "4.1.1" } }, @@ -4566,26 +5166,23 @@ "integrity": "sha1-w8T2xmO5I0WamqKZEtLQMfFQf4Q=" }, "finalhandler": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.3.tgz", - "integrity": "sha1-70fneVDpmXgOhgIqVg4yF+DQzIk=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", "requires": { - "debug": "2.6.7", + "debug": "2.6.9", "encodeurl": "1.0.1", "escape-html": "1.0.3", "on-finished": "2.3.0", - "parseurl": "1.3.1", + "parseurl": "1.3.2", "statuses": "1.3.1", "unpipe": "1.0.0" }, "dependencies": { - "debug": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", - "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", - "requires": { - "ms": "2.0.0" - } + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" } } }, @@ -4690,7 +5287,7 @@ "expand-tilde": "2.0.2", "is-plain-object": "2.0.4", "object.defaults": "1.1.0", - "object.pick": "1.2.0", + "object.pick": "1.3.0", "parse-filepath": "1.0.1" }, "dependencies": { @@ -4718,12 +5315,12 @@ "dev": true }, "flat-cache": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", - "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", "dev": true, "requires": { - "circular-json": "0.3.1", + "circular-json": "0.3.3", "del": "2.2.2", "graceful-fs": "4.1.11", "write": "0.2.1" @@ -4772,13 +5369,13 @@ "dev": true }, "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", + "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", "requires": { "asynckit": "0.4.0", "combined-stream": "1.0.5", - "mime-types": "2.1.15" + "mime-types": "2.1.17" } }, "formatio": { @@ -4787,18 +5384,19 @@ "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", "dev": true, "requires": { - "samsam": "1.2.1" + "samsam": "1.3.0" } }, "formidable": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.1.1.tgz", - "integrity": "sha1-lriIb3w8NQi5Mta9cMTTqI818ak=" + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.0.17.tgz", + "integrity": "sha1-71SRSQ+UM7cF+qdyScmQKa40hVk=", + "dev": true }, "forwarded": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz", - "integrity": "sha1-Ge+YdMSuHCl7zweP3mOgm2aoQ2M=" + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" }, "frameguard": { "version": "3.0.0", @@ -4806,9 +5404,9 @@ "integrity": "sha1-e8rUae57lukdEs6zlZx4I1qScuk=" }, "fresh": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz", - "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44=" + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, "from": { "version": "0.1.7", @@ -4830,7 +5428,7 @@ "requires": { "graceful-fs": "4.1.11", "jsonfile": "3.0.1", - "universalify": "0.1.0" + "universalify": "0.1.1" } }, "fs-readdir-recursive": { @@ -4851,7 +5449,7 @@ "dev": true, "optional": true, "requires": { - "nan": "2.6.2", + "nan": "2.7.0", "node-pre-gyp": "0.6.36" }, "dependencies": { @@ -5866,16 +6464,22 @@ } }, "function-bind": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz", - "integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E=" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true }, "g11n-pipeline": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/g11n-pipeline/-/g11n-pipeline-1.4.0.tgz", - "integrity": "sha1-G1i4Sdnl8s8LtcmaRVd87GeSDiw=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/g11n-pipeline/-/g11n-pipeline-2.0.2.tgz", + "integrity": "sha512-dwcp0ib/tyb3rBaIOZRZxCNU9IdqG8JWLHEMBIS6Vx5Q6n3QXo1I4Y85tiLOKY5GEPaBANV7CPYmhWUj6OMKxw==", "requires": { - "swagger-client": "2.2.21" + "swagger-client": "3.2.2" } }, "gaze": { @@ -5907,12 +6511,18 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=" }, + "get-params": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/get-params/-/get-params-0.1.2.tgz", + "integrity": "sha1-uuDfq6WIoMYNeDTA2Nwv9g7u8v4=", + "dev": true + }, "get-proxy": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-1.1.0.tgz", "integrity": "sha1-iUhUSRvFkbDxR9euVw9cZ4tyVus=", "requires": { - "rc": "1.2.1" + "rc": "1.2.2" } }, "get-stdin": { @@ -5920,19 +6530,17 @@ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=" }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "requires": { "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } } }, "glob": { @@ -6065,6 +6673,15 @@ "process": "0.5.2" } }, + "global-dirs": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.0.tgz", + "integrity": "sha1-ENNAOeDfBCcuJizyQiT3IJQ0308=", + "dev": true, + "requires": { + "ini": "1.3.4" + } + }, "global-modules": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", @@ -6084,7 +6701,7 @@ "homedir-polyfill": "1.0.1", "ini": "1.3.4", "is-windows": "0.2.0", - "which": "1.2.14" + "which": "1.3.0" } }, "globals": { @@ -6191,10 +6808,10 @@ "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-0.10.0.tgz", "integrity": "sha1-bhW6vuhf0d0U2NEoopW2g41SE24=", "requires": { - "gtoken": "1.2.2", + "gtoken": "1.2.3", "jws": "3.1.4", "lodash.noop": "3.0.1", - "request": "2.81.0" + "request": "2.83.0" } }, "google-p12-pem": { @@ -6247,6 +6864,14 @@ "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" }, + "graphlib": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.1.tgz", + "integrity": "sha1-QjUsUrovTQNctWbrkfc5X3bryVE=", + "requires": { + "lodash": "4.17.4" + } + }, "growl": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", @@ -6260,14 +6885,14 @@ "dev": true }, "gtoken": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-1.2.2.tgz", - "integrity": "sha1-Fyd2oanZasCfwioA9b6DzubeiCA=", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-1.2.3.tgz", + "integrity": "sha512-wQAJflfoqSgMWrSBk9Fg86q+sd6s7y6uJhIvvIPz++RElGlMtEqsdAR2oWwZ/WTEtp7P9xFbJRrT976oRgzJ/w==", "requires": { "google-p12-pem": "0.1.2", "jws": "3.1.4", - "mime": "1.3.4", - "request": "2.81.0" + "mime": "1.4.1", + "request": "2.83.0" } }, "gulp": { @@ -6280,7 +6905,7 @@ "chalk": "1.1.3", "deprecated": "0.0.1", "gulp-util": "3.0.8", - "interpret": "1.0.3", + "interpret": "1.0.4", "liftoff": "2.3.0", "minimist": "1.2.0", "orchestrator": "0.3.8", @@ -6311,7 +6936,7 @@ "integrity": "sha1-fAF25Lo/JExgWIoMSzIKRdGt784=", "dev": true, "requires": { - "babel-core": "6.25.0", + "babel-core": "6.26.0", "gulp-util": "3.0.8", "object-assign": "4.1.1", "replace-ext": "0.0.1", @@ -6358,7 +6983,7 @@ "clone-buffer": "1.0.0", "clone-stats": "1.0.0", "cloneable-readable": "1.0.0", - "remove-trailing-separator": "1.0.2", + "remove-trailing-separator": "1.1.0", "replace-ext": "1.0.0" } } @@ -6373,6 +6998,194 @@ "bufferstreams": "1.1.1", "eslint": "3.19.0", "gulp-util": "3.0.8" + }, + "dependencies": { + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "eslint": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "chalk": "1.1.3", + "concat-stream": "1.6.0", + "debug": "2.6.9", + "doctrine": "2.0.0", + "escope": "3.6.0", + "espree": "3.5.1", + "esquery": "1.0.0", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "glob": "7.1.2", + "globals": "9.18.0", + "ignore": "3.3.7", + "imurmurhash": "0.1.4", + "inquirer": "0.12.0", + "is-my-json-valid": "2.16.1", + "is-resolvable": "1.0.0", + "js-yaml": "3.10.0", + "json-stable-stringify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "1.2.1", + "progress": "1.1.8", + "require-uncached": "1.0.3", + "shelljs": "0.7.8", + "strip-bom": "3.0.0", + "strip-json-comments": "2.0.1", + "table": "3.8.3", + "text-table": "0.2.0", + "user-home": "2.0.0" + } + }, + "inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "dev": true, + "requires": { + "ansi-escapes": "1.4.0", + "ansi-regex": "2.1.1", + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "cli-width": "2.2.0", + "figures": "1.7.0", + "lodash": "4.17.4", + "readline2": "1.0.1", + "run-async": "0.1.0", + "rx-lite": "3.1.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "through": "2.3.8" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "dev": true + }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "dev": true, + "requires": { + "once": "1.4.0" + } + }, + "rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + }, + "shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "dev": true, + "requires": { + "glob": "7.1.2", + "interpret": "1.0.4", + "rechoir": "0.6.2" + } + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "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 + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "dev": true, + "requires": { + "ajv": "4.11.8", + "ajv-keywords": "1.5.1", + "chalk": "1.1.3", + "lodash": "4.17.4", + "slice-ansi": "0.0.4", + "string-width": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "requires": { + "os-homedir": "1.0.2" + } + } } }, "gulp-if": { @@ -6462,7 +7275,7 @@ "requires": { "accord": "0.27.3", "gulp-util": "3.0.8", - "less": "2.7.2", + "less": "2.7.3", "object-assign": "4.1.1", "through2": "2.0.3", "vinyl-sourcemaps-apply": "0.2.1" @@ -6486,7 +7299,7 @@ "colors": "1.1.2", "event-stream": "3.3.4", "gulp": "3.9.1", - "nodemon": "1.11.0" + "nodemon": "1.12.1" } }, "gulp-notify": { @@ -6560,9 +7373,9 @@ } }, "gulp-sourcemaps": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.0.tgz", - "integrity": "sha1-fMzomaijv8oVk6M0jQ+/Qd0/UeU=", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.1.tgz", + "integrity": "sha512-1qHCI3hdmsMdq/SUotxwUh/L8YzlI6J9zQ5ifNOtx4Y6KV5y5sGuORv1KZzWhuKtz/mXNh5xLESUtwC4EndCjA==", "dev": true, "requires": { "@gulp-sourcemaps/identity-map": "1.0.1", @@ -6570,10 +7383,10 @@ "acorn": "4.0.13", "convert-source-map": "1.5.0", "css": "2.2.1", - "debug-fabulous": "0.1.0", + "debug-fabulous": "0.2.1", "detect-newline": "2.1.0", "graceful-fs": "4.1.11", - "source-map": "0.5.6", + "source-map": "0.5.7", "strip-bom-string": "1.0.0", "through2": "2.0.3", "vinyl": "1.2.0" @@ -6658,7 +7471,7 @@ "array-uniq": "1.0.3", "beeper": "1.1.1", "chalk": "1.1.3", - "dateformat": "2.0.0", + "dateformat": "2.2.0", "fancy-log": "1.3.0", "gulplog": "1.0.0", "has-gulplog": "0.1.0", @@ -6698,9 +7511,9 @@ } }, "handlebars": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz", - "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=", + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", + "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", "dev": true, "requires": { "async": "1.5.2", @@ -6737,17 +7550,17 @@ } }, "har-schema": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", - "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" + "ajv": "5.3.0", + "har-schema": "2.0.0" } }, "has": { @@ -6756,7 +7569,7 @@ "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", "dev": true, "requires": { - "function-bind": "1.1.0" + "function-bind": "1.1.1" } }, "has-ansi": { @@ -6831,30 +7644,29 @@ "integrity": "sha1-eTpYlD+QKupXgXfXsDNfE/JpS3E=" }, "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.0", + "sntp": "2.1.0" } }, "helmet": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.6.1.tgz", - "integrity": "sha1-kfOqf6TJRnFZX7Vo39jChImjiL4=", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.9.0.tgz", + "integrity": "sha512-czCyS77TyanWlfVSoGlb9GBJV2Q2zJayKxU5uBw0N1TzDTs/qVNh1SL8Q688KU0i0Sb7lQ/oLtnaEqXzl2yWvA==", "requires": { - "connect": "3.6.2", "dns-prefetch-control": "0.1.0", "dont-sniff-mimetype": "1.0.0", "expect-ct": "0.1.0", "frameguard": "3.0.0", - "helmet-csp": "2.4.0", + "helmet-csp": "2.6.0", "hide-powered-by": "1.0.0", "hpkp": "2.0.0", - "hsts": "2.0.0", + "hsts": "2.1.0", "ienoopen": "1.0.0", "nocache": "2.0.0", "referrer-policy": "1.1.0", @@ -6862,15 +7674,15 @@ } }, "helmet-csp": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.4.0.tgz", - "integrity": "sha1-flOhVxZ6BkWq3XF30SrmxgXBhC4=", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.6.0.tgz", + "integrity": "sha512-n/oW9l6RtO4f9YvphsNzdvk1zITrSN7iRT8ojgrJu/N3mVdHl9zE4OjbiHWcR64JK32kbqx90/yshWGXcjUEhw==", "requires": { "camelize": "1.0.0", "content-security-policy-builder": "1.1.0", "dasherize": "2.0.0", "lodash.reduce": "4.6.0", - "platform": "1.3.3" + "platform": "1.3.4" } }, "hide-powered-by": { @@ -6879,20 +7691,21 @@ "integrity": "sha1-SoWtZYgfYoV/xwr3F0oRhNzM4ys=" }, "history": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/history/-/history-3.3.0.tgz", - "integrity": "sha1-/O3M6PEpdTcVRdc1RhAzV5ptrpw=", + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/history/-/history-4.7.2.tgz", + "integrity": "sha512-1zkBRWW6XweO0NBcjiphtVJVsIQ+SXF29z9DVkceeaSLVMFXHool+fdCZD4spDCfZJCILPILc3bm7Bc+HRi0nA==", "requires": { "invariant": "2.2.2", "loose-envify": "1.3.1", - "query-string": "4.3.4", + "resolve-pathname": "2.2.0", + "value-equal": "0.4.0", "warning": "3.0.0" } }, "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", + "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" }, "hoist-non-react-statics": { "version": "1.2.0", @@ -6928,12 +7741,9 @@ "integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI=" }, "hsts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.0.0.tgz", - "integrity": "sha1-pSI0xgcN7PIUsra3C7FE0H5Hdsc=", - "requires": { - "core-util-is": "1.0.2" - } + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.1.0.tgz", + "integrity": "sha512-zXhh/DqgrTXJ7erTN6Fh5k/xjMhDGXCqdYN3wvxUvGUQvnxcFfUd8E+6vLg/nk3ss1TYMb+DhRl25fYABioTvA==" }, "html-entities": { "version": "1.2.1", @@ -6977,14 +7787,14 @@ } }, "http-errors": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.1.tgz", - "integrity": "sha1-X4uO2YrKVFZWv1cplzh/kEpyIlc=", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", "requires": { - "depd": "1.1.0", + "depd": "1.1.1", "inherits": "2.0.3", "setprototypeof": "1.0.3", - "statuses": "1.3.1" + "statuses": "1.4.0" } }, "http-proxy": { @@ -6998,12 +7808,12 @@ } }, "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.0", + "assert-plus": "1.0.0", + "jsprim": "1.4.1", "sshpk": "1.13.1" } }, @@ -7039,6 +7849,11 @@ "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=", "dev": true }, + "https-pem": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/https-pem/-/https-pem-1.0.4.tgz", + "integrity": "sha1-802YaRbQUVY6f8a6lt2xwoY03Bg=" + }, "husky": { "version": "0.14.3", "resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz", @@ -7048,20 +7863,6 @@ "is-ci": "1.0.10", "normalize-path": "1.0.0", "strip-indent": "2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz", - "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", - "dev": true - }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true - } } }, "hyphenate-style-name": { @@ -7070,9 +7871,9 @@ "integrity": "sha1-MRYKNpMK2vH8BMYHT360FGXU7Es=" }, "iconv-lite": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", - "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=" + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" }, "ieee754": { "version": "1.1.8", @@ -7085,9 +7886,9 @@ "integrity": "sha1-NGpCj0dKrI9QzzeE6i0PFvYr2ms=" }, "ignore": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.3.tgz", - "integrity": "sha1-QyNS5XrM2HqzEQ6C0/6g5HgSFW0=", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", "dev": true }, "ignore-by-default": { @@ -7109,6 +7910,12 @@ "integrity": "sha1-IAgH8Rqw9ycQ6khVQt4IgHX2jNI=", "dev": true }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -7173,7 +7980,7 @@ "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-2.0.5.tgz", "integrity": "sha1-wVPH6I/YT+9cYC6VqBaLJ3BnH+c=", "requires": { - "bowser": "1.7.0", + "bowser": "1.8.1", "hyphenate-style-name": "1.0.2" } }, @@ -7185,7 +7992,7 @@ "ansi-escapes": "1.4.0", "chalk": "1.1.3", "cli-cursor": "1.0.2", - "cli-width": "2.1.0", + "cli-width": "2.2.0", "figures": "1.7.0", "lodash": "4.17.4", "mute-stream": "0.0.6", @@ -7205,9 +8012,9 @@ } }, "interpret": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", - "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.4.tgz", + "integrity": "sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA=", "dev": true }, "invariant": { @@ -7229,9 +8036,9 @@ "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" }, "ipaddr.js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.3.0.tgz", - "integrity": "sha1-HgOlL9rYOou7KyXL9JmLTP/NPew=" + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz", + "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=" }, "is": { "version": "3.2.1", @@ -7260,13 +8067,13 @@ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "1.8.0" + "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=" + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-builtin-module": { "version": "1.0.0", @@ -7288,7 +8095,7 @@ "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", "dev": true, "requires": { - "ci-info": "1.0.0" + "ci-info": "1.1.1" } }, "is-date-object": { @@ -7353,6 +8160,16 @@ "is-extglob": "1.0.0" } }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "0.1.0", + "is-path-inside": "1.0.0" + } + }, "is-integer": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-integer/-/is-integer-1.0.7.tgz", @@ -7362,9 +8179,9 @@ } }, "is-my-json-valid": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz", - "integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", + "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==", "dev": true, "requires": { "generate-function": "2.0.0", @@ -7572,8 +8389,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isobject": { "version": "3.0.1", @@ -7585,10 +8401,30 @@ "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", "requires": { - "node-fetch": "1.7.1", + "node-fetch": "1.7.3", "whatwg-fetch": "2.0.3" } }, + "isomorphic-form-data": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-form-data/-/isomorphic-form-data-0.0.1.tgz", + "integrity": "sha1-Am9ifgMrDNhBPsyHVZKLlKRosGI=", + "requires": { + "form-data": "1.0.1" + }, + "dependencies": { + "form-data": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz", + "integrity": "sha1-rjFduaSQf6BlUCMEpm13M0de43w=", + "requires": { + "async": "2.1.5", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + } + } + } + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -7601,9 +8437,9 @@ "dev": true, "requires": { "chalk": "1.1.3", - "coveralls": "2.13.1", + "coveralls": "2.13.3", "minimist": "1.2.0", - "rimraf": "2.6.1", + "rimraf": "2.6.2", "sum-up": "1.0.3" }, "dependencies": { @@ -7614,9 +8450,9 @@ "dev": true }, "rimraf": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "requires": { "glob": "7.1.2" @@ -7630,7 +8466,7 @@ "integrity": "sha1-nIDlOMEtP7lcjZu5VZ+gzAQEBf0=", "requires": { "character-parser": "1.2.1", - "clean-css": "3.4.27", + "clean-css": "3.4.28", "commander": "2.6.0", "constantinople": "3.0.2", "jstransformer": "0.0.2", @@ -7688,19 +8524,12 @@ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" }, "js-yaml": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.0.tgz", - "integrity": "sha512-0LoUNELX4S+iofCT8f4uEHIiRBR+c2AINyC8qRWfC6QNruLtxVZRJaPcu/xwMgFIgDxF25tGHaDjvxzJCNE9yw==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", "requires": { "argparse": "1.0.9", "esprima": "4.0.0" - }, - "dependencies": { - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" - } } }, "js2xmlparser": { @@ -7708,12 +8537,24 @@ "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-1.0.0.tgz", "integrity": "sha1-WhcPLo1kds5FQF4EgjJCUTeC/jA=" }, + "jsan": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/jsan/-/jsan-3.1.9.tgz", + "integrity": "sha1-JwVnbBBY8KfZrCZq0Daldpz6fJY=", + "dev": true + }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "optional": true }, + "jschardet": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.6.0.tgz", + "integrity": "sha512-xYuhvQ7I9PDJIGBWev9xm0+SMSed3ZDBAmvVjbFR1ZRLAF+vlXcQu6cRI9uAlj81rzikElRVteehwV7DuX2ZmQ==", + "dev": true + }, "jsesc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", @@ -7747,9 +8588,9 @@ "integrity": "sha1-PkQf2jCYvo0eMXGtWRvGKjPi1V8=" }, "json-loader": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.4.tgz", - "integrity": "sha1-i6oTZaYy9Yo8RtIBdfxgAsluN94=", + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", + "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", "dev": true }, "json-schema": { @@ -7757,10 +8598,16 @@ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + }, "json-stable-stringify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, "requires": { "jsonify": "0.0.0" } @@ -7793,7 +8640,8 @@ "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true }, "jsonlint": { "version": "1.6.2", @@ -7842,14 +8690,6 @@ "requires": { "brace-expansion": "1.1.8" } - }, - "omni-fetch": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/omni-fetch/-/omni-fetch-0.1.0.tgz", - "integrity": "sha1-Och1UMG7jdLMH7pUj0L1Jnpa7jk=", - "requires": { - "caw": "1.2.0" - } } } }, @@ -7865,21 +8705,14 @@ "dev": true }, "jsprim": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", - "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "requires": { "assert-plus": "1.0.0", - "extsprintf": "1.0.2", + "extsprintf": "1.3.0", "json-schema": "0.2.3", - "verror": "1.3.6" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } + "verror": "1.10.0" } }, "jstransformer": { @@ -7892,10 +8725,13 @@ } }, "jsx-ast-utils": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", - "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=", - "dev": true + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", + "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", + "dev": true, + "requires": { + "array-includes": "3.0.3" + } }, "jwa": { "version": "1.1.5", @@ -7933,7 +8769,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } }, "klaw": { @@ -7973,21 +8809,32 @@ "dev": true }, "less": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/less/-/less-2.7.2.tgz", - "integrity": "sha1-No1sxz4fsDmBGDKAkYdDxdz5s98=", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/less/-/less-2.7.3.tgz", + "integrity": "sha512-KPdIJKWcEAb02TuJtaLrhue0krtRLoRoo7x6BNJIBelO00t/CCdJQUnHW5V34OnHMWzIktSalJxRO+FvytQlCQ==", "dev": true, "requires": { "errno": "0.1.4", "graceful-fs": "4.1.11", "image-size": "0.5.5", - "mime": "1.3.4", + "mime": "1.4.1", "mkdirp": "0.5.1", "promise": "7.3.1", "request": "2.81.0", - "source-map": "0.5.6" + "source-map": "0.5.7" }, "dependencies": { + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "optional": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -7995,6 +8842,107 @@ "dev": true, "optional": true }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true, + "optional": true + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true, + "optional": true + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true, + "optional": true, + "requires": { + "boom": "2.10.1" + } + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "dev": true, + "optional": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + } + }, + "har-schema": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", + "dev": true, + "optional": true + }, + "har-validator": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "dev": true, + "optional": true, + "requires": { + "ajv": "4.11.8", + "har-schema": "1.0.5" + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true, + "optional": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", + "dev": true, + "optional": true + }, "promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", @@ -8004,6 +8952,54 @@ "requires": { "asap": "2.0.6" } + }, + "qs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", + "dev": true, + "optional": true + }, + "request": { + "version": "2.81.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.17", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.3", + "tunnel-agent": "0.6.0", + "uuid": "3.1.0" + } + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "optional": true, + "requires": { + "hoek": "2.16.3" + } } } }, @@ -8030,6 +9026,13 @@ "iconv-lite": "0.4.15", "libbase64": "0.1.0", "libqp": "1.1.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", + "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=" + } } }, "libqp": { @@ -8051,7 +9054,7 @@ "lodash.isstring": "4.0.1", "lodash.mapvalues": "4.6.0", "rechoir": "0.6.2", - "resolve": "1.3.3" + "resolve": "1.5.0" } }, "lightbox2": { @@ -8065,6 +9068,12 @@ "integrity": "sha512-JIKZ0xb6fZZYa3deZ0BgXCgX6HgV8Nx3mFGeFHmFWW8Fb2c08e0CyE+G3nalpD0xGvGssjGb1UdFr+PprxZEbw==", "dev": true }, + "linked-list": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/linked-list/-/linked-list-0.1.0.tgz", + "integrity": "sha1-eYsP+X0bkqT9CEgPVa6k6dSdN78=", + "dev": true + }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", @@ -8088,8 +9097,8 @@ "integrity": "sha1-MY9JkFzopwnft8w/FvPv47zx3QU=", "requires": { "in-publish": "2.0.0", - "semver": "5.3.0", - "source-map": "0.5.6" + "semver": "5.4.1", + "source-map": "0.5.7" } }, "loader-utils": { @@ -8098,36 +9107,61 @@ "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", "dev": true, "requires": { - "big.js": "3.1.3", + "big.js": "3.2.0", "emojis-list": "2.1.0", "json5": "0.5.1", "object-assign": "4.1.1" } }, "localtunnel": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-1.8.2.tgz", - "integrity": "sha1-kTBR6DKLUfda2KIq0fXFuMWZo1k=", + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-1.8.3.tgz", + "integrity": "sha1-3MWSL9hWUQN9S94k/ZMkjQsk6wU=", "dev": true, "requires": { - "debug": "2.2.0", - "openurl": "1.1.0", - "request": "2.78.0", + "debug": "2.6.8", + "openurl": "1.1.1", + "request": "2.81.0", "yargs": "3.29.0" }, "dependencies": { + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, "camelcase": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", "dev": true }, - "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", - "dev": true - }, "cliui": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", @@ -8139,84 +9173,139 @@ "wrap-ansi": "2.1.0" } }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true, + "requires": { + "boom": "2.10.1" + } }, "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", "dev": true, "requires": { - "ms": "0.7.1" + "ms": "2.0.0" } }, - "har-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", - "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", "dev": true, "requires": { - "chalk": "1.1.3", - "commander": "2.11.0", - "is-my-json-valid": "2.16.0", - "pinkie-promise": "2.0.1" + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" } }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "har-schema": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", "dev": true }, - "node-uuid": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", + "har-validator": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "dev": true, + "requires": { + "ajv": "4.11.8", + "har-schema": "1.0.5" + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "1.0.0" + } + }, + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", "dev": true }, "qs": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", - "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", "dev": true }, "request": { - "version": "2.78.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.78.0.tgz", - "integrity": "sha1-4cjew0bhyBkjskrNszfxHeyr6cw=", + "version": "2.81.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", "dev": true, "requires": { "aws-sign2": "0.6.0", "aws4": "1.6.0", - "caseless": "0.11.0", + "caseless": "0.12.0", "combined-stream": "1.0.5", "extend": "3.0.1", "forever-agent": "0.6.1", "form-data": "2.1.4", - "har-validator": "2.0.6", + "har-validator": "4.2.1", "hawk": "3.1.3", "http-signature": "1.1.1", "is-typedarray": "1.0.0", "isstream": "0.1.2", "json-stringify-safe": "5.0.1", - "mime-types": "2.1.15", - "node-uuid": "1.4.8", + "mime-types": "2.1.17", "oauth-sign": "0.8.2", - "qs": "6.3.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.1.1", "stringstream": "0.0.5", - "tough-cookie": "2.3.2", - "tunnel-agent": "0.4.3" + "tough-cookie": "2.3.3", + "tunnel-agent": "0.6.0", + "uuid": "3.1.0" } }, - "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } }, "window-size": { "version": "0.1.4", @@ -8263,11 +9352,6 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" }, - "lodash-compat": { - "version": "3.10.2", - "resolved": "https://registry.npmjs.org/lodash-compat/-/lodash-compat-3.10.2.tgz", - "integrity": "sha1-xpQBKKnTD46QLNLPmf0Muk7PwYM=" - }, "lodash-es": { "version": "4.17.4", "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.4.tgz", @@ -8400,6 +9484,11 @@ "lodash._root": "3.0.1" } }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=" + }, "lodash.flatten": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", @@ -8418,11 +9507,6 @@ "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", "dev": true }, - "lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" - }, "lodash.isfinite": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", @@ -8565,20 +9649,20 @@ "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" }, "loopback": { - "version": "2.38.3", - "resolved": "https://registry.npmjs.org/loopback/-/loopback-2.38.3.tgz", - "integrity": "sha1-YDuZ1X5+TSr950fX8zG7tBq4NV8=", + "version": "2.39.0", + "resolved": "https://registry.npmjs.org/loopback/-/loopback-2.39.0.tgz", + "integrity": "sha512-vTZJsN92zUbGj03MBrQYgtR8RCk8z+23OAplXAsv21FBnxdoW2Yrxvv7tyeno9uyl7252PZpvQokGaHtiWaW/Q==", "requires": { "async": "2.1.5", "bcryptjs": "2.4.3", - "body-parser": "1.17.2", + "body-parser": "1.18.2", "canonical-json": "0.0.4", "cookie-parser": "1.4.3", - "debug": "2.6.8", - "depd": "1.1.0", - "ejs": "2.5.6", + "debug": "2.6.9", + "depd": "1.1.1", + "ejs": "2.5.7", "errorhandler": "1.5.0", - "express": "4.15.3", + "express": "4.16.2", "inflection": "1.12.0", "isemail": "1.2.0", "loopback-connector-remote": "1.3.3", @@ -8586,25 +9670,25 @@ "loopback-phase": "1.4.1", "nodemailer": "2.7.2", "nodemailer-stub-transport": "1.1.0", - "serve-favicon": "2.4.3", + "serve-favicon": "2.4.5", "stable": "0.1.6", - "strong-globalize": "2.8.5", - "strong-remoting": "2.33.0", + "strong-globalize": "2.10.0", + "strong-remoting": "2.34.0", "uid2": "0.0.3", "underscore.string": "3.3.4" } }, "loopback-boot": { - "version": "2.25.0", - "resolved": "https://registry.npmjs.org/loopback-boot/-/loopback-boot-2.25.0.tgz", - "integrity": "sha512-rH+YxPmQnLod3oPuRUXUrEXdkahOXazbdJdPEqI5OjUBO8KHAXLdCPP3wdxWJKmtpkam7XWBDE93iyZFjwo3VA==", + "version": "2.27.0", + "resolved": "https://registry.npmjs.org/loopback-boot/-/loopback-boot-2.27.0.tgz", + "integrity": "sha512-PO8VMisNyUW8lKAN1oitJn6WveZOazqLPXSi4SRmE0asU6rlOR90dUW0Hr1wkYzVm46CQlKKHvuIOmguTvFN7g==", "requires": { "async": "0.9.2", "commondir": "0.0.1", - "debug": "2.6.8", + "debug": "2.6.9", "lodash": "3.10.1", "semver": "4.3.6", - "strong-globalize": "2.8.5", + "strong-globalize": "2.10.0", "toposort": "0.2.12" }, "dependencies": { @@ -8631,12 +9715,12 @@ "integrity": "sha1-4n7yIaNT7HgrFanQd15nTpr5fBs=", "dev": true, "requires": { - "cors": "2.8.3", - "debug": "2.6.8", - "depd": "1.1.0", + "cors": "2.8.4", + "debug": "2.6.9", + "depd": "1.1.1", "lodash": "3.10.1", "loopback-swagger": "2.9.0", - "strong-globalize": "2.8.5", + "strong-globalize": "2.10.0", "strong-swagger-ui": "21.0.2" }, "dependencies": { @@ -8654,7 +9738,7 @@ "integrity": "sha1-N9weQlVPS2QCZOjKH3CPJcPuq2Q=", "requires": { "passport": "0.3.2", - "strong-globalize": "2.8.5", + "strong-globalize": "2.10.0", "underscore": "1.8.3" }, "dependencies": { @@ -8680,10 +9764,10 @@ "integrity": "sha1-YK/CROMZGZdjkamXg4aFeB+ijlI=", "requires": { "async": "1.5.2", - "bluebird": "3.5.0", - "debug": "2.6.8", - "msgpack5": "3.4.1", - "strong-globalize": "2.8.5" + "bluebird": "3.5.1", + "debug": "2.6.9", + "msgpack5": "3.6.0", + "strong-globalize": "2.10.0" }, "dependencies": { "async": { @@ -8699,10 +9783,10 @@ "integrity": "sha1-12coqjFWJCpmxl69lyftz8ikc0k=", "requires": { "async": "1.5.2", - "debug": "2.6.8", + "debug": "2.6.9", "loopback-connector": "2.7.1", "mongodb": "2.1.21", - "strong-globalize": "2.8.5" + "strong-globalize": "2.10.0" }, "dependencies": { "async": { @@ -8767,8 +9851,8 @@ "resolved": "https://registry.npmjs.org/loopback-connector-remote/-/loopback-connector-remote-1.3.3.tgz", "integrity": "sha1-ePpyTk4ptNeqXcpVybNKC819Y+A=", "requires": { - "loopback-datasource-juggler": "2.55.0", - "strong-remoting": "2.33.0" + "loopback-datasource-juggler": "2.55.3", + "strong-remoting": "2.34.0" } }, "loopback-context": { @@ -8780,19 +9864,19 @@ } }, "loopback-datasource-juggler": { - "version": "2.55.0", - "resolved": "https://registry.npmjs.org/loopback-datasource-juggler/-/loopback-datasource-juggler-2.55.0.tgz", - "integrity": "sha1-eupPKwZW6G1Sufd69uECTW/shXo=", + "version": "2.55.3", + "resolved": "https://registry.npmjs.org/loopback-datasource-juggler/-/loopback-datasource-juggler-2.55.3.tgz", + "integrity": "sha1-RqPNj5O6VaCoz89xa91DpbSre3w=", "requires": { "async": "1.0.0", - "debug": "2.6.8", - "depd": "1.1.0", + "debug": "2.6.9", + "depd": "1.1.1", "inflection": "1.12.0", "loopback-connector": "2.7.1", "minimatch": "3.0.4", - "qs": "3.1.0", + "qs": "6.5.1", "shortid": "2.2.8", - "strong-globalize": "2.8.5", + "strong-globalize": "2.10.0", "traverse": "0.6.6", "uuid": "3.1.0" }, @@ -8801,11 +9885,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz", "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=" - }, - "qs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-3.1.0.tgz", - "integrity": "sha1-0OmudFIzoS3EP7TzBVu6RGJhFTw=" } } }, @@ -8815,8 +9894,8 @@ "integrity": "sha1-125asObsecxTcNPFMPY0hxAgvO4=", "requires": { "async": "0.9.2", - "debug": "2.6.8", - "strong-globalize": "2.8.5" + "debug": "2.6.9", + "strong-globalize": "2.10.0" }, "dependencies": { "async": { @@ -8833,10 +9912,10 @@ "dev": true, "requires": { "async": "1.5.2", - "debug": "2.6.8", - "ejs": "2.5.6", + "debug": "2.6.9", + "ejs": "2.5.7", "lodash": "3.10.1", - "strong-globalize": "2.8.5", + "strong-globalize": "2.10.0", "underscore.string": "2.3.3" }, "dependencies": { @@ -8891,6 +9970,15 @@ "yallist": "2.1.2" } }, + "lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", + "dev": true, + "requires": { + "es5-ext": "0.10.35" + } + }, "mailcomposer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-4.0.1.tgz", @@ -8900,6 +9988,23 @@ "libmime": "3.0.0" } }, + "make-dir": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz", + "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==", + "dev": true, + "requires": { + "pify": "3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, "make-error": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.0.tgz", @@ -8939,7 +10044,7 @@ "requires": { "charenc": "0.0.2", "crypt": "0.0.2", - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } }, "media-typer": { @@ -8947,6 +10052,30 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "requires": { + "mimic-fn": "1.1.0" + } + }, + "memoizee": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.11.tgz", + "integrity": "sha1-vemBdmPJ5A/bKk6hw2cpYIeujI8=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.35", + "es6-weak-map": "2.0.2", + "event-emitter": "0.3.5", + "is-promise": "2.1.0", + "lru-queue": "0.1.0", + "next-tick": "1.0.0", + "timers-ext": "0.1.2" + } + }, "memory-fs": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.3.0.tgz", @@ -9002,14 +10131,14 @@ } }, "method-override": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/method-override/-/method-override-2.3.9.tgz", - "integrity": "sha1-vRUfLONM8Bp2ykAKuVwBKxAtj3E=", + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/method-override/-/method-override-2.3.10.tgz", + "integrity": "sha1-49r41d7hDdLc59SuiNYrvud0drQ=", "requires": { - "debug": "2.6.8", + "debug": "2.6.9", "methods": "1.1.2", - "parseurl": "1.3.1", - "vary": "1.1.1" + "parseurl": "1.3.2", + "vary": "1.1.2" } }, "methods": { @@ -9035,27 +10164,43 @@ "normalize-path": "2.1.1", "object.omit": "2.0.1", "parse-glob": "3.0.4", - "regex-cache": "0.4.3" + "regex-cache": "0.4.4" + }, + "dependencies": { + "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" + } + } } }, "mime": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", - "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" }, "mime-db": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz", - "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=" + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" }, "mime-types": { - "version": "2.1.15", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz", - "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=", + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", + "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", "requires": { - "mime-db": "1.27.0" + "mime-db": "1.30.0" } }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=" + }, "min-document": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", @@ -9230,45 +10375,45 @@ "dev": true }, "moment": { - "version": "2.18.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz", - "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8=" + "version": "2.19.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.1.tgz", + "integrity": "sha1-VtoaLRy/AdOLfhr8McELz6GSkWc=" }, "moment-timezone": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.13.tgz", - "integrity": "sha1-mc5cfYJyYusPH3AgRBd/YHRde5A=", + "version": "0.5.14", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.14.tgz", + "integrity": "sha1-TrOP+VOLgBCLpGekWPPtQmjM/LE=", "requires": { - "moment": "2.18.1" + "moment": "2.19.1" } }, "mongodb": { - "version": "2.2.30", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.30.tgz", - "integrity": "sha1-jM2AH2dsgXIEDC8rR+lgKg1WNKs=", + "version": "2.2.33", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.33.tgz", + "integrity": "sha1-tTfEcdNKZlG0jzb9vyl1A0Dgi1A=", "requires": { "es6-promise": "3.2.1", - "mongodb-core": "2.1.14", + "mongodb-core": "2.1.17", "readable-stream": "2.2.7" } }, "mongodb-core": { - "version": "2.1.14", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.14.tgz", - "integrity": "sha1-E8uidkImtb49GJkq8Mljzl6g8P0=", + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.17.tgz", + "integrity": "sha1-pBizN6FKFJkPtRC5I97mqBMXPfg=", "requires": { "bson": "1.0.4", "require_optional": "1.0.1" } }, "morgan": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.8.2.tgz", - "integrity": "sha1-eErHc05KRTqcbm6GgKkyknXItoc=", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz", + "integrity": "sha1-0B+mxlhZt2/PMbPLU6OCGjEdgFE=", "requires": { - "basic-auth": "1.1.0", - "debug": "2.6.8", - "depd": "1.1.0", + "basic-auth": "2.0.0", + "debug": "2.6.9", + "depd": "1.1.1", "on-finished": "2.3.0", "on-headers": "1.0.1" } @@ -9309,13 +10454,30 @@ } }, "msgpack5": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/msgpack5/-/msgpack5-3.4.1.tgz", - "integrity": "sha1-NQ7zWJnGyHc3EP2E2IHd0zQKgRQ=", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/msgpack5/-/msgpack5-3.6.0.tgz", + "integrity": "sha512-6HuCZHA57WtNUzrKIvjJ8OMxigzveJ6D5i13y6TsgGu3X3zxABpuBvChpppOoGdB9SyWZcmqUs1fwUV/PpSQ7Q==", "requires": { "bl": "1.2.1", "inherits": "2.0.3", - "readable-stream": "2.2.7" + "readable-stream": "2.3.3", + "safe-buffer": "5.1.1" + }, + "dependencies": { + "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==", + "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" + } + } } }, "multi-glob": { @@ -9427,9 +10589,9 @@ } }, "nan": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz", - "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.7.0.tgz", + "integrity": "sha1-2Vv3IeyHfgjbJ27T/G63j5CDrUY=", "dev": true, "optional": true }, @@ -9489,6 +10651,15 @@ } } }, + "needle": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.0.1.tgz", + "integrity": "sha1-wh/JYc48NA+wgiUNpqCKMvOGMfE=", + "requires": { + "debug": "2.6.9", + "iconv-lite": "0.4.19" + } + }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", @@ -9502,24 +10673,29 @@ "inherits": "2.0.3" } }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, "nocache": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.0.0.tgz", "integrity": "sha1-ICtIAhoMTL3i34DeFaF0Q8i0OYA=" }, "node-emoji": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.7.0.tgz", - "integrity": "sha512-dYx345sjhPJUpWaVQKjP0/43y+nTcfBRTZfSciM3ZEbRGaU/9AKaHBPf7AJ9vOKcK0W3v67AgI4m4oo02NLHhQ==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.8.1.tgz", + "integrity": "sha512-+ktMAh1Jwas+TnGodfCfjUbJKoANqPaJFN0z0iqh41eqD8dvguNzcitVSBSVK1pidz0AqGbLKcoVuVLRVZ/aVg==", "requires": { - "lodash.toarray": "4.4.0", - "string.prototype.codepointat": "0.2.0" + "lodash.toarray": "4.4.0" } }, "node-fetch": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.1.tgz", - "integrity": "sha512-j8XsFGCLw79vWXkZtMSmmLaOk9z5SQ9bV/tkbZVCqvgwzrjAGq66igobLofHtF63NvMTp2WjytpsNTGKa+XRIQ==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", "requires": { "encoding": "0.1.12", "is-stream": "1.1.0" @@ -9554,7 +10730,7 @@ "stream-browserify": "2.0.1", "stream-http": "2.7.2", "string_decoder": "0.10.31", - "timers-browserify": "2.0.2", + "timers-browserify": "2.0.4", "tty-browserify": "0.0.0", "url": "0.11.0", "util": "0.10.3", @@ -9584,24 +10760,6 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "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 - } - } } } }, @@ -9612,9 +10770,9 @@ "dev": true, "requires": { "growly": "1.3.0", - "semver": "5.3.0", - "shellwords": "0.1.0", - "which": "1.2.14" + "semver": "5.4.1", + "shellwords": "0.1.1", + "which": "1.3.0" } }, "node-status-codes": { @@ -9664,7 +10822,7 @@ "resolved": "https://registry.npmjs.org/nodemailer-ses-transport/-/nodemailer-ses-transport-1.5.1.tgz", "integrity": "sha1-3AWYwb9T6GUuYy6PMWks4CLX3qk=", "requires": { - "aws-sdk": "2.83.0" + "aws-sdk": "2.141.0" } }, "nodemailer-shared": { @@ -9706,23 +10864,139 @@ "integrity": "sha1-WG24EB2zDLRDjrVGc3pBqtDPE9U=" }, "nodemon": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.11.0.tgz", - "integrity": "sha1-ImxWK9KnsT09dRi0mtSCijYj0Gw=", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.12.1.tgz", + "integrity": "sha1-mWpW3EnZ8Wu/G3ik3gjxNjSzh40=", "dev": true, "requires": { "chokidar": "1.7.0", - "debug": "2.6.8", - "es6-promise": "3.2.1", + "debug": "2.6.9", + "es6-promise": "3.3.1", "ignore-by-default": "1.0.1", "lodash.defaults": "3.1.2", "minimatch": "3.0.4", "ps-tree": "1.1.0", - "touch": "1.0.0", + "touch": "3.1.0", "undefsafe": "0.0.3", - "update-notifier": "0.5.0" + "update-notifier": "2.3.0" }, "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "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" + } + }, + "boxen": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.2.2.tgz", + "integrity": "sha1-Px1AMsMP/qnUsCwyLq8up0HcvOU=", + "dev": true, + "requires": { + "ansi-align": "2.0.0", + "camelcase": "4.1.0", + "chalk": "2.3.0", + "cli-boxes": "1.0.0", + "string-width": "2.1.1", + "term-size": "1.2.0", + "widest-line": "1.0.0" + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "configstore": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.1.tgz", + "integrity": "sha512-5oNkD/L++l0O6xGXxb1EWS7SivtjfGQlRyxJsYgE0Z495/L81e2h4/d3r969hoPXuFItzNOKMtsXgYG4c7dYvw==", + "dev": true, + "requires": { + "dot-prop": "4.2.0", + "graceful-fs": "4.1.11", + "make-dir": "1.1.0", + "unique-string": "1.0.0", + "write-file-atomic": "2.3.0", + "xdg-basedir": "3.0.0" + } + }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "dev": true, + "requires": { + "is-obj": "1.0.1" + } + }, + "es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=", + "dev": true + }, + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "dev": true, + "requires": { + "create-error-class": "3.0.2", + "duplexer3": "0.1.4", + "get-stream": "3.0.0", + "is-redirect": "1.0.0", + "is-retry-allowed": "1.1.0", + "is-stream": "1.1.0", + "lowercase-keys": "1.0.0", + "safe-buffer": "5.1.1", + "timed-out": "4.0.1", + "unzip-response": "2.0.1", + "url-parse-lax": "1.0.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "dev": true, + "requires": { + "package-json": "4.0.1" + } + }, "lodash.assign": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-3.2.0.tgz", @@ -9743,6 +11017,92 @@ "lodash.assign": "3.2.0", "lodash.restparam": "3.6.1" } + }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "dev": true, + "requires": { + "got": "6.7.1", + "registry-auth-token": "3.3.1", + "registry-url": "3.1.0", + "semver": "5.4.1" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", + "dev": true + }, + "update-notifier": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.3.0.tgz", + "integrity": "sha1-TognpruRUUCrCTVZ1wFOPruDdFE=", + "dev": true, + "requires": { + "boxen": "1.2.2", + "chalk": "2.3.0", + "configstore": "3.1.1", + "import-lazy": "2.1.0", + "is-installed-globally": "0.1.0", + "is-npm": "1.0.0", + "latest-version": "3.1.0", + "semver-diff": "2.1.0", + "xdg-basedir": "3.0.0" + } + }, + "write-file-atomic": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", + "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "imurmurhash": "0.1.4", + "signal-exit": "3.0.2" + } + }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "dev": true } } }, @@ -9783,7 +11143,7 @@ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "requires": { - "abbrev": "1.1.0" + "abbrev": "1.1.1" } }, "normalize-bool": { @@ -9798,18 +11158,15 @@ "requires": { "hosted-git-info": "2.5.0", "is-builtin-module": "1.0.0", - "semver": "5.3.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.0.2" - } + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz", + "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", + "dev": true }, "normalize-url": { "version": "1.9.1", @@ -9830,6 +11187,14 @@ "lodash": "4.17.4" } }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "2.0.1" + } + }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", @@ -9857,9 +11222,9 @@ "dev": true }, "object-inspect": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.2.2.tgz", - "integrity": "sha1-yCEV5PzIiK6hTWTCLk8X9qcNXlo=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.3.0.tgz", + "integrity": "sha512-OHHnLgLNXpM++GnJRyyhbr2bwl3pPVm4YvaraHrRvDt/N3r+s/gDVHciA7EJBTkijKXj61ssgSAikq1fb0IBRg==", "dev": true }, "object-keys": { @@ -9879,7 +11244,7 @@ "integrity": "sha1-scnMBE7xuf5jYG/BQau7MuFHMMw=", "requires": { "define-properties": "1.1.2", - "function-bind": "1.1.0", + "function-bind": "1.1.1", "object-keys": "1.0.11" } }, @@ -9917,23 +11282,20 @@ } }, "object.pick": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.2.0.tgz", - "integrity": "sha1-tTkr7peC2m2ft9avr1OXefEjTCs=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { - "isobject": "2.1.0" - }, - "dependencies": { - "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" - } - } + "isobject": "3.0.1" + } + }, + "omni-fetch": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/omni-fetch/-/omni-fetch-0.1.0.tgz", + "integrity": "sha1-Och1UMG7jdLMH7pUj0L1Jnpa7jk=", + "requires": { + "caw": "1.2.0" } }, "on-finished": { @@ -9963,18 +11325,19 @@ "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=" }, "opbeat": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/opbeat/-/opbeat-4.14.1.tgz", - "integrity": "sha512-8kcSCTNIXy5oW9lW+QFOL/r2iOs395JC5uU8BEtDYAGBTfPv+9nbPriUXc41duACtnIRbzW5qK0lG0vrOo28nw==", + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/opbeat/-/opbeat-4.16.0.tgz", + "integrity": "sha512-To2UxUptAZdnHsdjFV7hqVNSAxDobY30XiK9nMQAdb7Fuee24u3ALSunT7WXBL+5Huuf5kWiTRjhgi+mUUzFzw==", "requires": { "after-all-results": "2.0.0", "console-log-level": "1.4.0", "cookie": "0.3.1", "core-util-is": "1.0.2", - "debug": "2.6.8", + "debug": "3.1.0", "end-of-stream": "1.4.0", "fast-safe-stringify": "1.2.0", "hashlru": "2.2.0", + "https-pem": "1.0.4", "is-native": "1.0.1", "normalize-bool": "1.0.0", "object-assign": "4.1.1", @@ -9982,19 +11345,19 @@ "opbeat-release-tracker": "1.1.1", "redact-secrets": "1.0.0", "require-in-the-middle": "2.1.2", - "semver": "5.3.0", + "semver": "5.4.1", "sql-summary": "1.0.0", "stackman": "2.0.1", "unicode-byte-truncate": "1.0.0", "uuid": "3.1.0" }, "dependencies": { - "end-of-stream": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", - "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "requires": { - "once": "1.4.0" + "ms": "2.0.0" } } } @@ -10022,9 +11385,9 @@ "integrity": "sha1-QsPhjslUZra/DcQvOilFw/DK2Pw=" }, "openurl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.0.tgz", - "integrity": "sha1-4vIYnZmcBIIyAfCD8PGnzYkDGHo=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz", + "integrity": "sha1-OHW0sO96UsFW8NtB1GCduw+Us4c=", "dev": true }, "opn": { @@ -10046,9 +11409,9 @@ } }, "optional": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/optional/-/optional-0.1.3.tgz", - "integrity": "sha1-+HU3UXtZpecyz9jxjk9+6nq0dh4=" + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/optional/-/optional-0.1.4.tgz", + "integrity": "sha512-gtvrrCfkE08wKcgXaVwQVgwEQ8vel2dc5DDBn9RLQZ3YtmtkBss6A2HY6BnJH4N/4Ku97Ri/SF8sNWE2225WJw==" }, "optionator": { "version": "0.8.2", @@ -10075,7 +11438,8 @@ "options": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", - "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=" + "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", + "dev": true }, "orchestrator": { "version": "0.3.8", @@ -10126,11 +11490,13 @@ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", "requires": { - "lcid": "1.0.0" + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" } }, "os-name": { @@ -10188,6 +11554,11 @@ "object-assign": "4.1.1" } }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, "p-limit": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", @@ -10211,7 +11582,7 @@ "got": "5.7.1", "registry-auth-token": "3.3.1", "registry-url": "3.1.0", - "semver": "5.3.0" + "semver": "5.4.1" } }, "pad-right": { @@ -10309,9 +11680,9 @@ } }, "parseurl": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz", - "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY=" + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" }, "passport": { "version": "0.2.2", @@ -10386,7 +11757,7 @@ "requires": { "oauth": "0.9.15", "passport-strategy": "1.0.0", - "utils-merge": "1.0.0" + "utils-merge": "1.0.1" } }, "passport-oauth2": { @@ -10397,7 +11768,7 @@ "oauth": "0.9.15", "passport-strategy": "1.0.0", "uid2": "0.0.3", - "utils-merge": "1.0.0" + "utils-merge": "1.0.1" } }, "passport-strategy": { @@ -10439,6 +11810,11 @@ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", @@ -10495,9 +11871,9 @@ "dev": true }, "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pify": { "version": "2.3.0", @@ -10527,9 +11903,9 @@ } }, "platform": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.3.tgz", - "integrity": "sha1-ZGx3ARiZhwtqCQPnXpl+jlHadGE=" + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.4.tgz", + "integrity": "sha1-bw+xftqqSPIUQrOpdcBjEw8cPr0=" }, "plur": { "version": "1.0.0", @@ -10538,9 +11914,9 @@ "dev": true }, "pluralize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", "dev": true }, "pmx": { @@ -10548,7 +11924,7 @@ "resolved": "https://registry.npmjs.org/pmx/-/pmx-0.6.8.tgz", "integrity": "sha1-j51ttHB+puxzgwU3R1EDZ80fYzI=", "requires": { - "debug": "2.6.8", + "debug": "2.6.9", "json-stringify-safe": "5.0.1" } }, @@ -10610,9 +11986,9 @@ } }, "private": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", - "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=" + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" }, "process": { "version": "0.5.2", @@ -10625,9 +12001,9 @@ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", "dev": true }, "promise": { @@ -10639,12 +12015,13 @@ } }, "prop-types": { - "version": "15.5.10", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.5.10.tgz", - "integrity": "sha1-J5ffwxJhguOpXj37suiT3ddFYVQ=", + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz", + "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=", "requires": { - "fbjs": "0.8.12", - "loose-envify": "1.3.1" + "fbjs": "0.8.16", + "loose-envify": "1.3.1", + "object-assign": "4.1.1" } }, "prop-types-extra": { @@ -10656,12 +12033,12 @@ } }, "proxy-addr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.4.tgz", - "integrity": "sha1-J+VF9pYKRKYn2bREZ+NcG2tM4vM=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz", + "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=", "requires": { - "forwarded": "0.1.0", - "ipaddr.js": "1.3.0" + "forwarded": "0.1.2", + "ipaddr.js": "1.5.2" } }, "proxyquire": { @@ -10708,15 +12085,10 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" }, - "q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz", - "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=" - }, "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=" + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" }, "query-string": { "version": "4.3.4", @@ -10739,18 +12111,11 @@ "dev": true }, "raf": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/raf/-/raf-3.3.2.tgz", - "integrity": "sha1-DBO+C1tJtG921maSSNUnzysC/ic=", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.0.tgz", + "integrity": "sha512-pDP/NMRAXoTfrhCfyfSEwJAKLaxBU9eApMeBPB1TkDouZmvPerIClV8lTAd+uF8ZiTaVl69e1FCxQrAd/VTjGw==", "requires": { "performance-now": "2.1.0" - }, - "dependencies": { - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - } } }, "random-bytes": { @@ -10783,7 +12148,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -10794,7 +12159,7 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } } } @@ -10805,19 +12170,20 @@ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" }, "raw-body": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz", - "integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y=", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", "requires": { - "bytes": "2.4.0", - "iconv-lite": "0.4.15", + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", "unpipe": "1.0.0" } }, "rc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", - "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", + "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", "requires": { "deep-extend": "0.4.2", "ini": "1.3.4", @@ -10848,7 +12214,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-15.4.2.tgz", "integrity": "sha1-QfeZGyYYU5K6m66WyIiefgGDl+8=", "requires": { - "fbjs": "0.8.12", + "fbjs": "0.8.16", "loose-envify": "1.3.1", "object-assign": "4.1.1" } @@ -10858,7 +12224,7 @@ "resolved": "https://registry.npmjs.org/react-addons-css-transition-group/-/react-addons-css-transition-group-15.4.2.tgz", "integrity": "sha1-t4KINN+hQin+B3UOMx6KjLb7d0U=", "requires": { - "fbjs": "0.8.12", + "fbjs": "0.8.16", "object-assign": "4.1.1" } }, @@ -10867,24 +12233,23 @@ "resolved": "https://registry.npmjs.org/react-addons-shallow-compare/-/react-addons-shallow-compare-15.4.2.tgz", "integrity": "sha1-An/9lyDjoeCzKNzY/GLiFKDRdKU=", "requires": { - "fbjs": "0.8.12", + "fbjs": "0.8.16", "object-assign": "4.1.1" } }, "react-bootstrap": { - "version": "0.31.2", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-0.31.2.tgz", - "integrity": "sha512-6rEK6/Z0UStWkwROhNZ2RW+88AJ83d5i5nGJYoW88JoiAhkOd3MMKaJ4AQZKu+nZ3RWSNzHIKozuBb9N+ewOeA==", + "version": "0.31.5", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-0.31.5.tgz", + "integrity": "sha512-xgDihgX4QvYHmHzL87faDBMDnGfYyqcrqV0TEbWY+JizePOG1vfb8M3xJN+6MJ3kUYqDtQSZ7v/Q6Y5YDrkMdA==", "requires": { - "babel-runtime": "6.23.0", + "babel-runtime": "6.26.0", "classnames": "2.2.5", "dom-helpers": "3.2.1", "invariant": "2.2.2", "keycode": "2.1.9", - "prop-types": "15.5.10", + "prop-types": "15.6.0", "prop-types-extra": "1.0.1", - "react-overlays": "0.7.0", - "react-prop-types": "0.4.0", + "react-overlays": "0.7.4", "uncontrollable": "4.1.0", "warning": "3.0.0" } @@ -10895,14 +12260,14 @@ "integrity": "sha1-zWvW70WOweA1z9iz/nswyMeIPGw=", "requires": { "classnames": "2.2.5", - "codemirror": "5.27.4", + "codemirror": "5.31.0", "lodash.debounce": "4.0.8" }, "dependencies": { "codemirror": { - "version": "5.27.4", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.27.4.tgz", - "integrity": "sha512-oOpSTMT3gj27u8NSkkrciuIpCqID3dvb8UGpS7eEm/F1x1DVinp6+ROLR+B8hXdxqVFpCl2NrR2BQe7zd3uH7g==" + "version": "5.31.0", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.31.0.tgz", + "integrity": "sha512-LKbMZKoAz7pMmWuSEl253G6yyloSulj1kXfvYv+3n3I8wMiI7QwnCHwKM3Zw5S9ItNV28Layq0/ihQXWmn9T9w==" } } }, @@ -10911,7 +12276,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.4.2.tgz", "integrity": "sha1-AVNj8FsKH9Uq6e/dOgBg2QaVII8=", "requires": { - "fbjs": "0.8.12", + "fbjs": "0.8.16", "loose-envify": "1.3.1", "object-assign": "4.1.1" } @@ -10921,9 +12286,15 @@ "resolved": "https://registry.npmjs.org/react-fontawesome/-/react-fontawesome-1.6.1.tgz", "integrity": "sha1-7dzhfn3HMaoJ/UoYZoimF5OhbFw=", "requires": { - "prop-types": "15.5.10" + "prop-types": "15.6.0" } }, + "react-hot-api": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/react-hot-api/-/react-hot-api-0.4.7.tgz", + "integrity": "sha1-p+IqVtJS4Rq9k2a2EmTPRJLFgXE=", + "dev": true + }, "react-hot-loader": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-1.3.1.tgz", @@ -10934,12 +12305,6 @@ "source-map": "0.4.4" }, "dependencies": { - "react-hot-api": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/react-hot-api/-/react-hot-api-0.4.7.tgz", - "integrity": "sha1-p+IqVtJS4Rq9k2a2EmTPRJLFgXE=", - "dev": true - }, "source-map": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", @@ -10952,37 +12317,14 @@ } }, "react-images": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/react-images/-/react-images-0.5.4.tgz", - "integrity": "sha1-33YpgAko5LYBFUs+zOla7jWa4Jg=", + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/react-images/-/react-images-0.5.11.tgz", + "integrity": "sha512-plTXzBqlUNbZ7yC3KLCQFBRdGa0JozuaU74he1rlv+AjIIV4V7HWYZye2QOAmt9DNdcS2Yx9kzu6P8ac0io77A==", "requires": { "aphrodite": "0.5.0", - "prop-types": "15.5.10", - "react-scrolllock": "1.0.8", - "react-transition-group": "1.2.0" - }, - "dependencies": { - "react-scrolllock": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/react-scrolllock/-/react-scrolllock-1.0.8.tgz", - "integrity": "sha1-Su6FgWeDJ7lss4pyt6IOJhBmTlo=", - "requires": { - "create-react-class": "15.6.0", - "prop-types": "15.5.10" - } - }, - "react-transition-group": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-1.2.0.tgz", - "integrity": "sha1-tR/JIbDDg1p+98Vxx5/ILHPpIE8=", - "requires": { - "chain-function": "1.0.0", - "dom-helpers": "3.2.1", - "loose-envify": "1.3.1", - "prop-types": "15.5.10", - "warning": "3.0.0" - } - } + "prop-types": "15.6.0", + "react-scrolllock": "1.0.9", + "react-transition-group": "1.2.1" } }, "react-lazy-cache": { @@ -10998,10 +12340,17 @@ "resolved": "https://registry.npmjs.org/react-motion/-/react-motion-0.4.8.tgz", "integrity": "sha1-I7st0nwtjgDSKeRVctEF789Ao14=", "requires": { - "create-react-class": "15.6.0", + "create-react-class": "15.6.2", "performance-now": "0.2.0", - "prop-types": "15.5.10", - "raf": "3.3.2" + "prop-types": "15.6.0", + "raf": "3.4.0" + }, + "dependencies": { + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" + } } }, "react-no-ssr": { @@ -11009,29 +12358,21 @@ "resolved": "https://registry.npmjs.org/react-no-ssr/-/react-no-ssr-1.1.0.tgz", "integrity": "sha1-MTtI0uJgIPlp7ZjkcvEEgWBOPMg=", "requires": { - "babel-runtime": "6.23.0" + "babel-runtime": "6.26.0" } }, "react-notification": { "version": "git+https://github.com/BerkeleyTrue/react-notification.git#0c503b92a92cc1db843e6f8802d6d8b292546b5e" }, "react-overlays": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-0.7.0.tgz", - "integrity": "sha1-UxiY/1ZsflxyJurShjuM+fu1qYE=", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-0.7.4.tgz", + "integrity": "sha512-7vsooMx3siLAuEfTs8FYeP/lAORWWFXTO8PON3KgX0Htq1Oa+po6ioSjGyO0/GO5CVSMNhpWt6V2opeexHgBuQ==", "requires": { "classnames": "2.2.5", "dom-helpers": "3.2.1", - "prop-types": "15.5.10", - "react-prop-types": "0.4.0", - "warning": "3.0.0" - } - }, - "react-prop-types": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/react-prop-types/-/react-prop-types-0.4.0.tgz", - "integrity": "sha1-+ZsL+0AGkpya8gUefBQUpcdbk9A=", - "requires": { + "prop-types": "15.6.0", + "prop-types-extra": "1.0.1", "warning": "3.0.0" } }, @@ -11045,49 +12386,43 @@ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-4.4.8.tgz", "integrity": "sha1-57wd0QDotk6WrIIS2xEyObni4I8=", "requires": { - "create-react-class": "15.6.0", + "create-react-class": "15.6.2", "hoist-non-react-statics": "1.2.0", "invariant": "2.2.2", "lodash": "4.17.4", "loose-envify": "1.3.1", - "prop-types": "15.5.10" + "prop-types": "15.6.0" } }, - "react-router": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-3.0.5.tgz", - "integrity": "sha1-w7eHN1gEWou8lWKu9P9LyMznwTY=", + "react-scrolllock": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/react-scrolllock/-/react-scrolllock-1.0.9.tgz", + "integrity": "sha1-fJw8DM4u1VBCrygItkg7hbEhzcs=", "requires": { - "create-react-class": "15.6.0", - "history": "3.3.0", - "hoist-non-react-statics": "1.2.0", - "invariant": "2.2.2", + "create-react-class": "15.6.2", + "prop-types": "15.6.0" + } + }, + "react-transition-group": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-1.2.1.tgz", + "integrity": "sha512-CWaL3laCmgAFdxdKbhhps+c0HRGF4c+hdM4H23+FI1QBNUyx/AMeIJGWorehPNSaKnQNOAxL7PQmqMu78CDj3Q==", + "requires": { + "chain-function": "1.0.0", + "dom-helpers": "3.2.1", "loose-envify": "1.3.1", - "prop-types": "15.5.10", + "prop-types": "15.6.0", "warning": "3.0.0" } }, - "react-router-bootstrap": { - "version": "0.23.3", - "resolved": "https://registry.npmjs.org/react-router-bootstrap/-/react-router-bootstrap-0.23.3.tgz", - "integrity": "sha1-lww1xTwExh+2sRDU/2Uafopzsro=", - "requires": { - "prop-types": "15.5.10" - } - }, - "react-router-redux": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/react-router-redux/-/react-router-redux-4.0.8.tgz", - "integrity": "sha1-InQDWWtRUeGCN32rg1tdRfD4BU4=" - }, "react-youtube": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/react-youtube/-/react-youtube-7.4.0.tgz", - "integrity": "sha1-00bDDsd+7GGHHowHhM7yyyxptj0=", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/react-youtube/-/react-youtube-7.5.0.tgz", + "integrity": "sha1-MXWpxOB4FkzxA85Lx4Cp5MpPH5Q=", "requires": { - "lodash.isequal": "4.5.0", - "prop-types": "15.5.10", - "youtube-player": "4.2.3" + "lodash": "4.17.4", + "prop-types": "15.6.0", + "youtube-player": "5.4.0" } }, "read-all-stream": { @@ -11169,7 +12504,7 @@ "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "dev": true, "requires": { - "resolve": "1.3.3" + "resolve": "1.5.0" } }, "redact-secrets": { @@ -11188,6 +12523,21 @@ "requires": { "indent-string": "2.1.0", "strip-indent": "1.0.1" + }, + "dependencies": { + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "requires": { + "get-stdin": "4.0.1" + } + } } }, "reduce-reducers": { @@ -11196,9 +12546,9 @@ "integrity": "sha1-+htHGLxSkqcd3R5dg5yb6pdw8Us=" }, "redux": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.1.tgz", - "integrity": "sha512-iEVTlORM5mv6xb3ZAOyrVehVUD+W87jdFAX6SYVgZh3/SQAWFSxTRJOqPWQdvo4VN4lJkNDvqKlBXBabsJTSkA==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz", + "integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==", "requires": { "lodash": "4.17.4", "lodash-es": "4.17.4", @@ -11222,16 +12572,26 @@ "resolved": "https://registry.npmjs.org/redux-create-types/-/redux-create-types-0.0.1.tgz", "integrity": "sha1-MgiSwdwXOgFix17ToB0tp09ytbo=", "requires": { - "babel-runtime": "6.23.0", + "babel-runtime": "6.26.0", "invariant": "2.2.2" } }, + "redux-devtools-instrument": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/redux-devtools-instrument/-/redux-devtools-instrument-1.8.2.tgz", + "integrity": "sha1-XpHP5ALnkNrj/S8NI197fYSwn/4=", + "dev": true, + "requires": { + "lodash": "4.17.4", + "symbol-observable": "1.0.4" + } + }, "redux-epic": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/redux-epic/-/redux-epic-0.3.0.tgz", "integrity": "sha1-g/SioK4fowK/QC397KNi1jB9xr8=", "requires": { - "debug": "2.6.8", + "debug": "2.6.9", "invariant": "2.2.2", "react": "15.4.2", "react-addons-shallow-compare": "15.4.2", @@ -11247,6 +12607,29 @@ } } }, + "redux-first-router": { + "version": "1.9.19", + "resolved": "https://registry.npmjs.org/redux-first-router/-/redux-first-router-1.9.19.tgz", + "integrity": "sha512-4DAFllxOQe5b/RJSeIWTVBDmnzQf2EWu6rTP5MkWjK9JkssNVaT+MI76391gao4AQq/q0yfzOsRYshEWKO4Xow==", + "requires": { + "path-to-regexp": "1.7.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "requires": { + "isarray": "0.0.1" + } + } + } + }, "redux-form": { "version": "5.3.6", "resolved": "https://registry.npmjs.org/redux-form/-/redux-form-5.3.6.tgz", @@ -11256,7 +12639,7 @@ "hoist-non-react-statics": "1.2.0", "invariant": "2.2.2", "is-promise": "2.1.0", - "prop-types": "15.5.10", + "prop-types": "15.6.0", "react-lazy-cache": "3.0.1" } }, @@ -11266,46 +12649,40 @@ "integrity": "sha1-NXdOtzW/UPtsB46DM0tHI1AgfXk=" }, "regenerate": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz", - "integrity": "sha1-0ZQcZ7rUN+G+dkM63Vs4X5WxkmA=" + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", + "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==" }, "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", + "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==" }, "regenerator-transform": { - "version": "0.9.11", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.9.11.tgz", - "integrity": "sha1-On0GdSDLe3F2dp61/4aGkb7+EoM=", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0", - "private": "0.1.7" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "private": "0.1.8" } }, "regex-cache": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", - "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", + "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", - "is-primitive": "2.0.0" + "is-equal-shallow": "0.1.3" } }, - "regexp-quote": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/regexp-quote/-/regexp-quote-0.0.0.tgz", - "integrity": "sha1-Hg9GUMhi3L/tVP1CsUjpuxch/PI=" - }, "regexpu-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", "requires": { - "regenerate": "1.3.2", + "regenerate": "1.3.3", "regjsgen": "0.2.0", "regjsparser": "0.1.5" } @@ -11315,7 +12692,7 @@ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz", "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=", "requires": { - "rc": "1.2.1", + "rc": "1.2.2", "safe-buffer": "5.1.1" } }, @@ -11324,7 +12701,7 @@ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", "requires": { - "rc": "1.2.1" + "rc": "1.2.2" } }, "regjsgen": { @@ -11347,10 +12724,46 @@ } } }, + "remote-redux-devtools": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/remote-redux-devtools/-/remote-redux-devtools-0.5.12.tgz", + "integrity": "sha1-QsuV36nlTB2WcTF8Xnu6QeaMrsI=", + "dev": true, + "requires": { + "jsan": "3.1.9", + "querystring": "0.2.0", + "redux-devtools-instrument": "1.8.2", + "remotedev-utils": "0.1.4", + "rn-host-detect": "1.1.3", + "socketcluster-client": "5.5.2" + } + }, + "remotedev-serialize": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/remotedev-serialize/-/remotedev-serialize-0.1.0.tgz", + "integrity": "sha1-B0do6Yy3qoBvRZlO6wyK+VEg7jI=", + "dev": true, + "requires": { + "jsan": "3.1.9" + } + }, + "remotedev-utils": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/remotedev-utils/-/remotedev-utils-0.1.4.tgz", + "integrity": "sha1-ZDcAgZqUNngHPHXrGF6B2WYgs0g=", + "dev": true, + "requires": { + "get-params": "0.1.2", + "jsan": "3.1.9", + "lodash": "4.17.4", + "remotedev-serialize": "0.1.0", + "shortid": "2.2.8" + } + }, "remove-trailing-separator": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz", - "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=", + "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": { @@ -11379,30 +12792,30 @@ "dev": true }, "request": { - "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "version": "2.83.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", + "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", "requires": { - "aws-sign2": "0.6.0", + "aws-sign2": "0.7.0", "aws4": "1.6.0", "caseless": "0.12.0", "combined-stream": "1.0.5", "extend": "3.0.1", "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", + "form-data": "2.3.1", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", "is-typedarray": "1.0.0", "isstream": "0.1.2", "json-stringify-safe": "5.0.1", - "mime-types": "2.1.15", + "mime-types": "2.1.17", "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", + "performance-now": "2.1.0", + "qs": "6.5.1", "safe-buffer": "5.1.1", "stringstream": "0.0.5", - "tough-cookie": "2.3.2", + "tough-cookie": "2.3.3", "tunnel-agent": "0.6.0", "uuid": "3.1.0" } @@ -11418,7 +12831,7 @@ "integrity": "sha1-vduJMW1FvNsI4sYYa9Lm6Bmo7q4=", "requires": { "module-details-from-path": "1.0.3", - "resolve": "1.3.3" + "resolve": "1.5.0" } }, "require-main-filename": { @@ -11450,7 +12863,7 @@ "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", "requires": { "resolve-from": "2.0.0", - "semver": "5.3.0" + "semver": "5.4.1" } }, "requires-port": { @@ -11465,9 +12878,9 @@ "integrity": "sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc=" }, "resolve": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.3.3.tgz", - "integrity": "sha1-ZVkHw0aahoDcLeOidaj91paR8OU=", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", "requires": { "path-parse": "1.0.5" } @@ -11487,6 +12900,11 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" }, + "resolve-pathname": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.2.0.tgz", + "integrity": "sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg==" + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -11499,7 +12917,7 @@ "integrity": "sha1-sSTeXE+6/LpUH0j/pzlw9KpFa08=", "dev": true, "requires": { - "debug": "2.6.8", + "debug": "2.6.9", "minimatch": "3.0.4" } }, @@ -11667,6 +13085,12 @@ "integrity": "sha1-K/GYveFnys+lHAqSjoS2i74XH84=", "dev": true }, + "rn-host-detect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/rn-host-detect/-/rn-host-detect-1.1.3.tgz", + "integrity": "sha1-JC124vpIXEjXUUFuZbfM5ZaWnpE=", + "dev": true + }, "rndm": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/rndm/-/rndm-1.2.0.tgz", @@ -11694,29 +13118,39 @@ } }, "rx-lite": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", "dev": true }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true, + "requires": { + "rx-lite": "4.0.8" + } + }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, "samsam": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.2.1.tgz", - "integrity": "sha1-7dOQk6MYQ3DLhZJDsr3yVefY6mc=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", + "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", "dev": true }, "sanitize-html": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.14.1.tgz", - "integrity": "sha1-cw/6Ikm98YMz7/5FsoYXPJxa0Lg=", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.15.0.tgz", + "integrity": "sha512-1jWLToWx8ZV53Z1Jg+2fHl8dNFsxvQt2Cmrk4o/z1+MUdB5EXSU0QVuzlGGhfp7cQrYbEEfMO/TUWHfkBUqujQ==", "requires": { "htmlparser2": "3.9.2", - "regexp-quote": "0.0.0", + "lodash.escaperegexp": "4.1.2", + "srcset": "1.0.0", "xtend": "4.0.1" }, "dependencies": { @@ -11745,17 +13179,55 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, + "sc-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/sc-channel/-/sc-channel-1.0.6.tgz", + "integrity": "sha1-s4vUepk+eCkPvFNGeGf2sqCghjk=", + "dev": true, + "requires": { + "sc-emitter": "1.1.0" + } + }, + "sc-emitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/sc-emitter/-/sc-emitter-1.1.0.tgz", + "integrity": "sha1-7xGdQiL0xk+Ie0hpZO8REWzdDnU=", + "dev": true, + "requires": { + "component-emitter": "1.2.0" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.0.tgz", + "integrity": "sha1-zNETqGOI0GSC0D3j/H35hSa6jv4=", + "dev": true + } + } + }, + "sc-errors": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/sc-errors/-/sc-errors-1.3.3.tgz", + "integrity": "sha1-wAvEx2apcMyNWTfQjNWOkx19rgU=", + "dev": true + }, + "sc-formatter": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sc-formatter/-/sc-formatter-3.0.1.tgz", + "integrity": "sha512-Jl2bH8zUtKn70JJIIPTEfWGDXK+TB9wV55C/zwSoDum4T1X1bsIBudO1QkxOG2RZMgkcKexfGQLlDCH37c/4fg==", + "dev": true + }, "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" }, "semver-diff": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", "requires": { - "semver": "5.3.0" + "semver": "5.4.1" } }, "semver-regex": { @@ -11765,32 +13237,29 @@ "dev": true }, "send": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/send/-/send-0.15.3.tgz", - "integrity": "sha1-UBP5+ZAj31DRvZiSwZ4979HVMwk=", + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", + "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==", "requires": { - "debug": "2.6.7", - "depd": "1.1.0", + "debug": "2.6.9", + "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.1", - "mime": "1.3.4", + "etag": "1.8.1", + "fresh": "0.5.2", + "http-errors": "1.6.2", + "mime": "1.4.1", "ms": "2.0.0", "on-finished": "2.3.0", "range-parser": "1.2.0", "statuses": "1.3.1" }, "dependencies": { - "debug": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", - "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", - "requires": { - "ms": "2.0.0" - } + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" } } }, @@ -11801,27 +13270,20 @@ "dev": true }, "serialize-javascript": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.3.0.tgz", - "integrity": "sha1-hqTzdS9cfkcpVEmwu7Y9ZLpTPwU=" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.4.0.tgz", + "integrity": "sha1-fJWFFNtqwkQ6irwGLcn3iGp/YAU=" }, "serve-favicon": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.4.3.tgz", - "integrity": "sha1-WYaxewUCZCtkHCH4GLGszjICXSM=", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.4.5.tgz", + "integrity": "sha512-s7F8h2NrslMkG50KxvlGdj+ApSwaLex0vexuJ9iFf3GLTIp1ph/l1qZvRe9T9TJEYZgmq72ZwJ2VYiAEtChknw==", "requires": { - "etag": "1.8.0", - "fresh": "0.5.0", + "etag": "1.8.1", + "fresh": "0.5.2", "ms": "2.0.0", - "parseurl": "1.3.1", - "safe-buffer": "5.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", - "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=" - } + "parseurl": "1.3.2", + "safe-buffer": "5.1.1" } }, "serve-index": { @@ -11830,13 +13292,13 @@ "integrity": "sha1-fF2WwT+xMRAfk8HFd0+FFqHnjTs=", "dev": true, "requires": { - "accepts": "1.3.3", + "accepts": "1.3.4", "batch": "0.5.3", "debug": "2.2.0", "escape-html": "1.0.3", "http-errors": "1.5.1", - "mime-types": "2.1.15", - "parseurl": "1.3.1" + "mime-types": "2.1.17", + "parseurl": "1.3.2" }, "dependencies": { "debug": { @@ -11856,7 +13318,7 @@ "requires": { "inherits": "2.0.3", "setprototypeof": "1.0.2", - "statuses": "1.3.1" + "statuses": "1.4.0" } }, "ms": { @@ -11874,14 +13336,14 @@ } }, "serve-static": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.3.tgz", - "integrity": "sha1-n0uhni8wMMVH+K+ZEHg47DjVseI=", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", + "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==", "requires": { "encodeurl": "1.0.1", "escape-html": "1.0.3", - "parseurl": "1.3.1", - "send": "0.15.3" + "parseurl": "1.3.2", + "send": "0.16.1" } }, "server-destroy": { @@ -11933,7 +13395,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-2.0.1.tgz", "integrity": "sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU=", "requires": { - "is-buffer": "1.1.5" + "is-buffer": "1.1.6" } }, "lazy-cache": { @@ -11943,15 +13405,28 @@ } } }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, "shelljs": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" }, "shellwords": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.0.tgz", - "integrity": "sha1-Zq/Ue2oSky2Qccv9mKUueFzQuhQ=", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", "dev": true }, "shimmer": { @@ -12011,25 +13486,25 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "sinon": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-2.3.7.tgz", - "integrity": "sha1-FFFhSi6qsFu02HbBM1zUATLsUSc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-2.4.1.tgz", + "integrity": "sha512-vFTrO9Wt0ECffDYIPSP/E5bBugt0UjcBQOfQUMh66xzkyPEnhl/vM2LRZi2ajuTdkH07sA6DzrM6KvdvGIH8xw==", "dev": true, "requires": { - "diff": "3.3.0", + "diff": "3.4.0", "formatio": "1.2.0", "lolex": "1.6.0", "native-promise-only": "0.8.1", "path-to-regexp": "1.7.0", - "samsam": "1.2.1", + "samsam": "1.3.0", "text-encoding": "0.6.4", "type-detect": "4.0.3" }, "dependencies": { "diff": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.0.tgz", - "integrity": "sha512-w0XZubFWn0Adlsapj9EAWX0FqWdO4tz8kc3RiYdWLh4k/V8PTb6i0SMgXt0vRM3zyKnT8tKO7mUlieRQHIjMNg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", + "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==", "dev": true }, "isarray": { @@ -12066,10 +13541,21 @@ "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" }, "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } + } }, "slide": { "version": "1.1.6", @@ -12091,40 +13577,42 @@ } }, "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", "requires": { - "hoek": "2.16.3" + "hoek": "4.2.0" } }, "snyk": { - "version": "1.36.2", - "resolved": "https://registry.npmjs.org/snyk/-/snyk-1.36.2.tgz", - "integrity": "sha1-iL5yqNp1oC6SDyvn9YMEArXg60E=", + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/snyk/-/snyk-1.47.0.tgz", + "integrity": "sha1-LIanNKhC/fwYuX32gqkdQZ/scPM=", "requires": { - "abbrev": "1.1.0", + "abbrev": "1.1.1", "ansi-escapes": "1.4.0", "chalk": "1.1.3", "configstore": "1.4.0", - "debug": "2.6.8", + "debug": "2.6.9", "es6-promise": "3.2.1", "hasbin": "1.2.3", "inquirer": "1.0.3", + "needle": "2.0.1", "open": "0.0.5", "os-name": "1.0.3", - "request": "2.81.0", - "semver": "5.3.0", + "semver": "5.4.1", "snyk-config": "1.0.1", - "snyk-gradle-plugin": "1.0.2", + "snyk-go-plugin": "1.3.8", + "snyk-gradle-plugin": "1.2.0", "snyk-module": "1.8.1", - "snyk-mvn-plugin": "1.0.0", + "snyk-mvn-plugin": "1.1.0", + "snyk-nuget-plugin": "1.0.0", "snyk-policy": "1.7.1", - "snyk-python-plugin": "1.2.2", + "snyk-python-plugin": "1.4.0", "snyk-recursive-readdir": "2.0.0", "snyk-resolve": "1.0.0", "snyk-resolve-deps": "1.7.0", - "snyk-sbt-plugin": "1.0.2", + "snyk-sbt-plugin": "1.2.0", "snyk-tree": "1.0.0", "snyk-try-require": "1.2.0", "tempfile": "1.1.1", @@ -12133,22 +13621,6 @@ "update-notifier": "0.5.0", "url": "0.11.0", "uuid": "3.1.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - } } }, "snyk-config": { @@ -12156,15 +13628,24 @@ "resolved": "https://registry.npmjs.org/snyk-config/-/snyk-config-1.0.1.tgz", "integrity": "sha1-8nrsJJiyQCescZIUAmUhWRERUI8=", "requires": { - "debug": "2.6.8", + "debug": "2.6.9", "nconf": "0.7.2", "path-is-absolute": "1.0.1" } }, + "snyk-go-plugin": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/snyk-go-plugin/-/snyk-go-plugin-1.3.8.tgz", + "integrity": "sha512-jHdC6+wEgSCV287PWFPx/9yb7NaLIi/jf4qxxu4CfNVjepA7Nk88LWAb4URQ/kJbw2IY7lz9z6OJlr/npqt9MA==", + "requires": { + "graphlib": "2.1.1", + "toml": "2.3.3" + } + }, "snyk-gradle-plugin": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/snyk-gradle-plugin/-/snyk-gradle-plugin-1.0.2.tgz", - "integrity": "sha512-mFGMmSLj3lIBZay0pJ+8+Y5QB6B55ywOaLYA85TJHQfsoRp3A5LpQvTd6jBWDCo+oZw65wrDQxu4EsGEew+Y6Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/snyk-gradle-plugin/-/snyk-gradle-plugin-1.2.0.tgz", + "integrity": "sha512-FucMRR+Rc6LBaSIYxiBl+jvb7R00SgA0QfMT+RGxLIZlDk1lagvA/jIkv+mRadwHVSV/ShIFSZLmS7agfPclVg==", "requires": { "clone-deep": "0.3.0" } @@ -12174,25 +13655,42 @@ "resolved": "https://registry.npmjs.org/snyk-module/-/snyk-module-1.8.1.tgz", "integrity": "sha1-MdUID7HA39b6hWfdNKUj/QK/H8o=", "requires": { - "debug": "2.6.8", + "debug": "2.6.9", "hosted-git-info": "2.5.0" } }, "snyk-mvn-plugin": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/snyk-mvn-plugin/-/snyk-mvn-plugin-1.1.0.tgz", + "integrity": "sha512-eWRTGzSNnuhLF49015ZyRgYsNC7N0uXltNZVvaLrKClL9tERG7uX9IAWMwKyMeyLS9Dlpml4zLZ5nYY/Z+aU1Q==" + }, + "snyk-nuget-plugin": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/snyk-mvn-plugin/-/snyk-mvn-plugin-1.0.0.tgz", - "integrity": "sha512-23K3VGMKS3W2l53cyQyb+EnbScKW3idUmylKRJRYEcK95ACzghdpI7tU4XBv5FH9LX60QybOskHYs0Phkim2Aw==" + "resolved": "https://registry.npmjs.org/snyk-nuget-plugin/-/snyk-nuget-plugin-1.0.0.tgz", + "integrity": "sha512-csMnwFrwb4ZBkDV6z93WZ0tjclWD1aiJIdjYjM4qJMmoYLRMyLOBdvmcOAoEwp24gJpkd8MreTT3hgCLqK+LJw==", + "requires": { + "es6-promise": "4.1.1", + "xml2js": "0.4.19", + "zip": "1.2.0" + }, + "dependencies": { + "es6-promise": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.1.1.tgz", + "integrity": "sha512-OaU1hHjgJf+b0NzsxCg7NdIYERD6Hy/PEmFLTjw+b65scuisG3Kt4QoTvJ66BBkPZ581gr0kpoVzKnxniM8nng==" + } + } }, "snyk-policy": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/snyk-policy/-/snyk-policy-1.7.1.tgz", "integrity": "sha1-5BO2vUr2BQxeX0RSh5CeTpigmyI=", "requires": { - "debug": "2.6.8", + "debug": "2.6.9", "es6-promise": "3.2.1", - "js-yaml": "3.9.0", + "js-yaml": "3.10.0", "lodash.clonedeep": "4.5.0", - "semver": "5.3.0", + "semver": "5.4.1", "snyk-module": "1.8.1", "snyk-resolve": "1.0.0", "snyk-try-require": "1.2.0", @@ -12200,9 +13698,9 @@ } }, "snyk-python-plugin": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/snyk-python-plugin/-/snyk-python-plugin-1.2.2.tgz", - "integrity": "sha512-JVQS77d7hRtsqGFPe7rVk8EsgqEPhBYJvtfLsRZzrLdk++T161rUVxXdYkWpUdrUO+uCUENqQX1ypi65Aj6tbg==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/snyk-python-plugin/-/snyk-python-plugin-1.4.0.tgz", + "integrity": "sha512-cxcxNBAf7tRFfUF2s6GsdgIjRYU9oVzIZEhGkzbKpG12pgipH7b+xKX0h3Cvta+llImW859dP2Bnnf7meJPl1Q==" }, "snyk-recursive-readdir": { "version": "2.0.0", @@ -12227,7 +13725,7 @@ "resolved": "https://registry.npmjs.org/snyk-resolve/-/snyk-resolve-1.0.0.tgz", "integrity": "sha1-u+kZbTf1fDklHmvnXM3Vsgl+maI=", "requires": { - "debug": "2.6.8", + "debug": "2.6.9", "then-fs": "2.0.0" } }, @@ -12236,15 +13734,15 @@ "resolved": "https://registry.npmjs.org/snyk-resolve-deps/-/snyk-resolve-deps-1.7.0.tgz", "integrity": "sha1-E3Q6BYQ33/iQuq9DfDM8lmp0PLY=", "requires": { - "abbrev": "1.1.0", + "abbrev": "1.1.1", "ansicolors": "0.3.2", "clite": "0.3.0", - "debug": "2.6.8", + "debug": "2.6.9", "es6-promise": "3.2.1", "lodash": "4.17.4", "lru-cache": "4.1.1", "minimist": "1.2.0", - "semver": "5.3.0", + "semver": "5.4.1", "snyk-module": "1.8.1", "snyk-resolve": "1.0.0", "snyk-tree": "1.0.0", @@ -12260,9 +13758,9 @@ } }, "snyk-sbt-plugin": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/snyk-sbt-plugin/-/snyk-sbt-plugin-1.0.2.tgz", - "integrity": "sha512-j+vVwqlrbMr6LSEM6sLOCykdOsRXhhJ23y8FdJHo22UfTVbRMCr6MFLrlMkNmsHcWhIFuzgqIdjkP5LMRdRktA==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/snyk-sbt-plugin/-/snyk-sbt-plugin-1.2.0.tgz", + "integrity": "sha512-H4/n8/1+7WEgHLJRnzNbvI8p2biE8EBFhM++qJJU1tlIWOHy+Dl1UhwKgFiY8PSXmbQDZccabWje4XlK4a4oAA==" }, "snyk-tree": { "version": "1.0.0", @@ -12277,7 +13775,7 @@ "resolved": "https://registry.npmjs.org/snyk-try-require/-/snyk-try-require-1.2.0.tgz", "integrity": "sha1-MPwrEcBwZFke41eAyCa+kTEvIUQ=", "requires": { - "debug": "2.6.8", + "debug": "2.6.9", "es6-promise": "3.2.1", "lodash.clonedeep": "4.5.0", "lru-cache": "4.1.1", @@ -12368,6 +13866,12 @@ "to-array": "0.1.4" }, "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, "debug": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", @@ -12397,12 +13901,6 @@ "json3": "3.3.2" }, "dependencies": { - "component-emitter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", - "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=", - "dev": true - }, "debug": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", @@ -12426,6 +13924,53 @@ } } }, + "socketcluster-client": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/socketcluster-client/-/socketcluster-client-5.5.2.tgz", + "integrity": "sha1-nUNp4Oci/35V5UIsLUT1r+Gv8Sg=", + "dev": true, + "requires": { + "base-64": "0.1.0", + "clone": "2.1.1", + "linked-list": "0.1.0", + "querystring": "0.2.0", + "sc-channel": "1.0.6", + "sc-emitter": "1.1.0", + "sc-errors": "1.3.3", + "sc-formatter": "3.0.1", + "ws": "3.0.0" + }, + "dependencies": { + "clone": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", + "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", + "dev": true + }, + "safe-buffer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", + "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=", + "dev": true + }, + "ultron": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.0.tgz", + "integrity": "sha1-sHoualQagV/Go0zNRTO67DB8qGQ=", + "dev": true + }, + "ws": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.0.0.tgz", + "integrity": "sha1-mN2wAFbIOQy3Ued4h4hJf5kQO2w=", + "dev": true, + "requires": { + "safe-buffer": "5.0.1", + "ultron": "1.1.0" + } + } + } + }, "socks": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.9.tgz", @@ -12450,9 +13995,9 @@ "dev": true }, "source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" }, "source-map-resolve": { "version": "0.3.1", @@ -12467,11 +14012,11 @@ } }, "source-map-support": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.15.tgz", - "integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=", + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "requires": { - "source-map": "0.5.6" + "source-map": "0.5.7" } }, "source-map-url": { @@ -12533,12 +14078,28 @@ "resolved": "https://registry.npmjs.org/sql-summary/-/sql-summary-1.0.0.tgz", "integrity": "sha1-OeOlHY2F5Gc5g2/H1n0GVLFzo58=" }, + "srcset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-1.0.0.tgz", + "integrity": "sha1-pWad4StC87HV6D7QPHEEb8SPQe8=", + "requires": { + "array-uniq": "1.0.3", + "number-is-nan": "1.0.1" + } + }, "sse": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/sse/-/sse-0.0.6.tgz", "integrity": "sha1-MZJGHfo4x4Qk3Zv46gJWGaElqhA=", "requires": { "options": "0.0.6" + }, + "dependencies": { + "options": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", + "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=" + } } }, "sshpk": { @@ -12554,13 +14115,6 @@ "getpass": "0.1.7", "jsbn": "0.1.1", "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } } }, "stable": { @@ -12575,16 +14129,16 @@ "requires": { "after-all-results": "2.0.0", "async-cache": "1.1.0", - "debug": "2.6.8", + "debug": "2.6.9", "error-callsites": "1.0.1", "load-source-map": "1.0.0", "path-is-absolute": "1.0.1" } }, "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" }, "store": { "version": "git+https://github.com/berkeleytrue/store.js.git#562c990c2f8018b6401a640aada8e9f667554fe1" @@ -12674,11 +14228,6 @@ "strip-ansi": "3.0.1" } }, - "string.prototype.codepointat": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.0.tgz", - "integrity": "sha1-aybpvTr8qnvjtCabUm3huCAArHg=" - }, "string.prototype.trim": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", @@ -12686,8 +14235,8 @@ "dev": true, "requires": { "define-properties": "1.1.2", - "es-abstract": "1.7.0", - "function-bind": "1.1.0" + "es-abstract": "1.9.0", + "function-bind": "1.1.1" } }, "string_decoder": { @@ -12735,20 +14284,16 @@ "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", "dev": true }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "requires": { - "get-stdin": "4.0.1" - }, - "dependencies": { - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" - } - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true }, "strip-json-comments": { "version": "1.0.4", @@ -12756,26 +14301,26 @@ "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=" }, "strong-globalize": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/strong-globalize/-/strong-globalize-2.8.5.tgz", - "integrity": "sha512-yTxstPkC1NDqqURNpnJIaECc21Xt4ZhyMZx/5vRmG4FAWnhc5P2SCL5QxJ5gmhetf9SrWf4AvaHuVAYa4BZORg==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/strong-globalize/-/strong-globalize-2.10.0.tgz", + "integrity": "sha512-g2nNtA6YKBDXhIe6TC/b0lInge8WxcAlFss9OKNGiUHUlOkhIdBHn9AGMLVbKyfI9T8ijEBATcwFIPayWUpOdQ==", "requires": { "async": "1.5.2", - "debug": "2.6.8", - "esprima": "3.1.3", + "debug": "3.1.0", + "esprima": "4.0.0", "estraverse": "4.2.0", - "g11n-pipeline": "1.4.0", + "g11n-pipeline": "2.0.2", "htmlparser2": "3.9.2", "lodash": "4.17.4", "md5": "2.2.1", "mkdirp": "0.5.1", "mktmpdir": "0.1.1", - "optional": "0.1.3", - "os-locale": "1.4.0", + "optional": "0.1.4", + "os-locale": "2.1.0", "posix-getopt": "1.2.0", "word-count": "0.2.2", "xtend": "4.0.1", - "yamljs": "0.2.10" + "yamljs": "0.3.0" }, "dependencies": { "async": { @@ -12783,6 +14328,14 @@ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, "entities": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", @@ -12804,28 +14357,28 @@ } }, "strong-remoting": { - "version": "2.33.0", - "resolved": "https://registry.npmjs.org/strong-remoting/-/strong-remoting-2.33.0.tgz", - "integrity": "sha1-fdlHwVi+n7bsu7L1KKJvSGjBV5Q=", + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/strong-remoting/-/strong-remoting-2.34.0.tgz", + "integrity": "sha512-Llm7SbEcYAe4HwPShjnN4wVRlK1afOHWqs1afQYyILfBpPFUh9OXFGH9msdAR8VyulvxlZznTisyrV2GJSCSIQ==", "requires": { "async": "2.1.5", - "body-parser": "1.17.2", - "cors": "2.8.3", - "debug": "2.6.8", - "depd": "1.1.0", + "body-parser": "1.18.2", + "cors": "2.8.4", + "debug": "2.6.9", + "depd": "1.1.1", "eventemitter2": "2.2.2", - "express": "4.15.3", + "express": "4.16.2", "inflection": "1.12.0", "jayson": "1.2.2", "js2xmlparser": "1.0.0", "loopback-phase": "1.4.1", "mux-demux": "3.7.9", - "qs": "6.4.0", - "request": "2.81.0", + "qs": "6.5.1", + "request": "2.83.0", "sse": "0.0.6", - "strong-globalize": "2.8.5", + "strong-globalize": "2.10.0", "traverse": "0.6.6", - "xml2js": "0.4.17" + "xml2js": "0.4.19" } }, "strong-swagger-ui": { @@ -12843,56 +14396,33 @@ "chalk": "1.1.3" } }, - "superagent": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-2.3.0.tgz", - "integrity": "sha1-cDUpoHFOV+EjlZ3e+84ZOy5Q0RU=", - "requires": { - "component-emitter": "1.2.1", - "cookiejar": "2.1.1", - "debug": "2.6.8", - "extend": "3.0.1", - "form-data": "1.0.0-rc4", - "formidable": "1.1.1", - "methods": "1.1.2", - "mime": "1.3.4", - "qs": "6.4.0", - "readable-stream": "2.2.7" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" - }, - "form-data": { - "version": "1.0.0-rc4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.0-rc4.tgz", - "integrity": "sha1-BaxrwiIntD5EYfSIFhVUaZ1Pi14=", - "requires": { - "async": "1.5.2", - "combined-stream": "1.0.5", - "mime-types": "2.1.15" - } - } - } - }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" }, "swagger-client": { - "version": "2.2.21", - "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-2.2.21.tgz", - "integrity": "sha1-WWa+I0dyRm5EcW9l4yAIFm2u66Q=", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.2.2.tgz", + "integrity": "sha1-xHDretdPDo56hQ3DjPQaeEIg9oA=", "requires": { + "babel-runtime": "6.26.0", "btoa": "1.1.2", - "cookiejar": "2.1.1", - "js-yaml": "3.9.0", - "lodash-compat": "3.10.2", - "q": "1.5.0", - "superagent": "2.3.0" + "deep-extend": "0.4.2", + "fast-json-patch": "1.1.8", + "isomorphic-fetch": "2.2.1", + "isomorphic-form-data": "0.0.1", + "js-yaml": "3.10.0", + "lodash": "4.16.2", + "qs": "6.5.1", + "url": "0.11.0" + }, + "dependencies": { + "lodash": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.16.2.tgz", + "integrity": "sha1-PmJtuCcEimmSgaihJSJjJs/A5lI=" + } } }, "symbol-observable": { @@ -12901,23 +14431,23 @@ "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0=" }, "table": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", "dev": true, "requires": { - "ajv": "4.11.8", - "ajv-keywords": "1.5.1", - "chalk": "1.1.3", + "ajv": "5.3.0", + "ajv-keywords": "2.1.1", + "chalk": "2.3.0", "lodash": "4.17.4", - "slice-ansi": "0.0.4", - "string-width": "2.1.0" + "slice-ansi": "1.0.0", + "string-width": "2.1.1" }, "dependencies": { "ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", "dev": true }, "ansi-regex": { @@ -12926,6 +14456,32 @@ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, + "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" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -12933,9 +14489,9 @@ "dev": true }, "string-width": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.0.tgz", - "integrity": "sha1-AwZkVh/BRslCPsfZeP4kV0N/5tA=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "2.0.0", @@ -12950,6 +14506,15 @@ "requires": { "ansi-regex": "3.0.0" } + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } } } }, @@ -12961,14 +14526,14 @@ "requires": { "re-emitter": "1.1.3", "readable-stream": "2.2.7", - "split": "1.0.0", + "split": "1.0.1", "trim": "0.0.1" }, "dependencies": { "split": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.0.tgz", - "integrity": "sha1-xDlc5oOrzSVLwo/h2rtuXCfc/64=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", "dev": true, "requires": { "through": "2.3.8" @@ -13013,21 +14578,21 @@ "dev": true }, "tape": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.7.0.tgz", - "integrity": "sha512-ePzu2KfZYVtq0v+KKGxBJ9HJWYZ4MaQWeGabD+KpVdMKRen3NJPf6EiwA5BxfMkhQPGtCwnOFWelcB39bhOUng==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.8.0.tgz", + "integrity": "sha512-TWILfEnvO7I8mFe35d98F6T5fbLaEtbFTG/lxWvid8qDfFTxt19EBijWmB4j3+Hoh5TfHE2faWs73ua+EphuBA==", "dev": true, "requires": { "deep-equal": "1.0.1", "defined": "1.0.0", "for-each": "0.3.2", - "function-bind": "1.1.0", + "function-bind": "1.1.1", "glob": "7.1.2", "has": "1.0.1", "inherits": "2.0.3", "minimist": "1.2.0", - "object-inspect": "1.2.2", - "resolve": "1.3.3", + "object-inspect": "1.3.0", + "resolve": "1.4.0", "resumer": "0.0.0", "string.prototype.trim": "1.1.2", "through": "2.3.8" @@ -13038,6 +14603,15 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true + }, + "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" + } } } }, @@ -13057,13 +14631,22 @@ } } }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "dev": true, + "requires": { + "execa": "0.7.0" + } + }, "ternary-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ternary-stream/-/ternary-stream-2.0.1.tgz", "integrity": "sha1-Bk5Im0tb9gumpre8fy9cJ07Pgmk=", "dev": true, "requires": { - "duplexify": "3.5.0", + "duplexify": "3.5.1", "fork-stream": "0.0.4", "merge-stream": "1.0.1", "through2": "2.0.3" @@ -13135,14 +14718,24 @@ "integrity": "sha1-lYYL/MXHbCd/j4Mm/Q9bLiDrohc=" }, "timers-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.2.tgz", - "integrity": "sha1-q0iDz1l9zVCvIRNJoA+8pWrIa4Y=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.4.tgz", + "integrity": "sha512-uZYhyU3EX8O7HQP+J9fTVYwsq90Vr68xPEFo7yrVImIxYvHgukBEgOB/SgGoorWVTzGM/3Z+wUNnboA4M8jWrg==", "dev": true, "requires": { "setimmediate": "1.0.5" } }, + "timers-ext": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.2.tgz", + "integrity": "sha1-YcxHp2wavTGV8UUn+XjViulMUgQ=", + "dev": true, + "requires": { + "es5-ext": "0.10.35", + "next-tick": "1.0.0" + } + }, "tmp": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz", @@ -13188,15 +14781,20 @@ "resolved": "https://registry.npmjs.org/to-utf8/-/to-utf8-0.0.1.tgz", "integrity": "sha1-0Xrqcv8vujm55DYBvns/9y4ImFI=" }, + "toml": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/toml/-/toml-2.3.3.tgz", + "integrity": "sha512-O7L5hhSQHxuufWUdcTRPfuTh3phKfAZ/dqfxZFoxPCj2RYmpaSGLEIs016FCXItQwNr08yefUB5TSjzRYnajTA==" + }, "toposort": { "version": "0.2.12", "resolved": "https://registry.npmjs.org/toposort/-/toposort-0.2.12.tgz", "integrity": "sha1-x9KYTz1IwhcxXMMtdwiIt3lJHoE=" }, "touch": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-1.0.0.tgz", - "integrity": "sha1-RJy+LbrlqMgDjjDXH6D/RklHxN4=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", "dev": true, "requires": { "nopt": "1.0.10" @@ -13208,15 +14806,15 @@ "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", "dev": true, "requires": { - "abbrev": "1.1.0" + "abbrev": "1.1.1" } } } }, "tough-cookie": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", - "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", "requires": { "punycode": "1.4.1" } @@ -13334,7 +14932,7 @@ "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", "requires": { "media-typer": "0.3.0", - "mime-types": "2.1.15" + "mime-types": "2.1.17" } }, "typedarray": { @@ -13344,16 +14942,16 @@ "dev": true }, "ua-parser-js": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.13.tgz", - "integrity": "sha1-zZ3S+GSTs/RNvu7zeA/adMXuFL4=" + "version": "0.7.17", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", + "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==" }, "uglify-js": { "version": "2.8.29", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", "requires": { - "source-map": "0.5.6", + "source-map": "0.5.7", "uglify-to-browserify": "1.0.2", "yargs": "3.10.0" }, @@ -13459,10 +15057,19 @@ "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=", "dev": true }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true, + "requires": { + "crypto-random-string": "1.0.0" + } + }, "universalify": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.0.tgz", - "integrity": "sha1-nrHEZR3rzGcMyU8adXYjMruWd3g=", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", + "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=", "dev": true }, "unpipe": { @@ -13494,7 +15101,7 @@ "resolved": "https://registry.npmjs.org/got/-/got-3.3.1.tgz", "integrity": "sha1-5dDtSvVfw+701WAHdp2YGSvLLso=", "requires": { - "duplexify": "3.5.0", + "duplexify": "3.5.1", "infinity-agent": "2.0.3", "is-redirect": "1.0.0", "is-stream": "1.1.0", @@ -13550,9 +15157,9 @@ "dev": true }, "url": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", "requires": { "punycode": "1.3.2", "querystring": "0.2.0" @@ -13602,9 +15209,9 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "utils-merge": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", - "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { "version": "3.1.0", @@ -13621,9 +15228,9 @@ } }, "validate-commit-msg": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/validate-commit-msg/-/validate-commit-msg-2.12.2.tgz", - "integrity": "sha1-bVAVMxvxlsIq+4gNPzO87x3q/qY=", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/validate-commit-msg/-/validate-commit-msg-2.14.0.tgz", + "integrity": "sha1-5Tg2kQEsuycNzAvCpO/+vhSJDqw=", "dev": true, "requires": { "conventional-commit-types": "2.2.0", @@ -13646,17 +15253,24 @@ "resolved": "https://registry.npmjs.org/validator/-/validator-6.3.0.tgz", "integrity": "sha1-R84j7Y1Ord+p1LjvAHG2zxB418g=" }, + "value-equal": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz", + "integrity": "sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw==" + }, "vary": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.1.tgz", - "integrity": "sha1-Z1Neu2lMHVIldFeYRmUyP1h+jTc=" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, "verror": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", - "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "requires": { - "extsprintf": "1.0.2" + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" } }, "vinyl": { @@ -13788,7 +15402,7 @@ "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", "dev": true, "requires": { - "source-map": "0.5.6" + "source-map": "0.5.7" } }, "vm-browserify": { @@ -13905,7 +15519,7 @@ "dev": true, "requires": { "async": "0.2.10", - "source-map": "0.5.6", + "source-map": "0.5.7", "uglify-to-browserify": "1.0.2", "yargs": "3.10.0" }, @@ -13974,15 +15588,16 @@ } }, "webpack-dev-middleware": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.11.0.tgz", - "integrity": "sha1-CWkdCXOjCtH4Ksc6EuIIfwpHVPk=", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.0.tgz", + "integrity": "sha1-007++y7dp+HTtdvgcolRMhllFwk=", "dev": true, "requires": { "memory-fs": "0.4.1", - "mime": "1.3.4", + "mime": "1.4.1", "path-is-absolute": "1.0.1", - "range-parser": "1.2.0" + "range-parser": "1.2.0", + "time-stamp": "2.0.0" }, "dependencies": { "memory-fs": { @@ -13994,13 +15609,19 @@ "errno": "0.1.4", "readable-stream": "2.2.7" } + }, + "time-stamp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-2.0.0.tgz", + "integrity": "sha1-lcakRTDhW6jW9KPsuMOj+sRto1c=", + "dev": true } } }, "webpack-hot-middleware": { - "version": "2.18.2", - "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.18.2.tgz", - "integrity": "sha512-dB7uOnUWsojZIAC6Nwi5v3tuaQNd2i7p4vF5LsJRyoTOgr2fRYQdMKQxRZIZZaz0cTPBX8rvcWU1A6/n7JTITg==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.20.0.tgz", + "integrity": "sha512-AYwVG9DCvMoXbwx8eK16CbJY3Ltwap44lW3T7hFsE0U3zRwtViHMw1DFpY5hMwXNqKsUk3HtNcf3PoV+gIxJeg==", "dev": true, "requires": { "ansi-html": "0.0.7", @@ -14010,9 +15631,9 @@ } }, "webpack-manifest-plugin": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-1.1.2.tgz", - "integrity": "sha512-IdeSoftCEzeVrkTy4XFsYBLQk7fWiKPUKUvSdb68/alpoKHP9X9MhMcYdkCIdAXclUhBIcyL03wFLr76wZG45A==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-1.3.2.tgz", + "integrity": "sha512-MX60Bv2G83Zks9pi3oLOmRgnPAnwrlMn+lftMrWBm199VQjk46/xgzBi9lPfpZldw2+EI2S+OevuLIaDuxCWRw==", "dev": true, "requires": { "fs-extra": "0.30.0", @@ -14105,12 +15726,6 @@ "qs": "0.4.2" } }, - "formidable": { - "version": "1.0.17", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.0.17.tgz", - "integrity": "sha1-71SRSQ+UM7cF+qdyScmQKa40hVk=", - "dev": true - }, "mime": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.4.tgz", @@ -14149,10 +15764,9 @@ "dev": true }, "which": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", - "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", - "dev": true, + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", "requires": { "isexe": "2.0.0" } @@ -14175,7 +15789,7 @@ "resolved": "https://registry.npmjs.org/win-release/-/win-release-1.1.1.tgz", "integrity": "sha1-X6VeAr58qTTt/BJmVjLoSbcuUgk=", "requires": { - "semver": "5.3.0" + "semver": "5.4.1" } }, "window-size": { @@ -14289,21 +15903,18 @@ } }, "xml2js": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz", - "integrity": "sha1-F76T6q4/O3eTWceVtBlwWogX6Gg=", + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", "requires": { "sax": "1.2.4", - "xmlbuilder": "4.2.1" + "xmlbuilder": "9.0.4" } }, "xmlbuilder": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz", - "integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=", - "requires": { - "lodash": "4.17.4" - } + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.4.tgz", + "integrity": "sha1-UZy0ymhtAFqEINNJbz8MruzKWA8=" }, "xmldom": { "version": "0.1.27", @@ -14340,9 +15951,9 @@ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, "yamljs": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.2.10.tgz", - "integrity": "sha1-SBzHwlynOvWfWR8MluPOVsdXpA8=", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", + "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", "requires": { "argparse": "1.0.9", "glob": "7.1.2" @@ -14380,6 +15991,15 @@ "wrap-ansi": "2.1.0" } }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "1.0.0" + } + }, "yargs-parser": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", @@ -14407,15 +16027,33 @@ "dev": true }, "youtube-player": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/youtube-player/-/youtube-player-4.2.3.tgz", - "integrity": "sha1-ACSLewErKuBhd8d9qNiTptAcqSw=", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/youtube-player/-/youtube-player-5.4.0.tgz", + "integrity": "sha1-nj/IofyuamzIkUDnrdfHzYYpnW4=", "requires": { - "babel-runtime": "6.23.0", + "debug": "2.6.9", "load-script": "1.0.0", - "lodash": "4.17.4", "sister": "3.0.0" } + }, + "zip": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zip/-/zip-1.2.0.tgz", + "integrity": "sha1-rQrUImUwm+QutW/IYZThfCTmapw=", + "requires": { + "bops": "0.1.1" + }, + "dependencies": { + "bops": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/bops/-/bops-0.1.1.tgz", + "integrity": "sha1-Bi4CqNqoAfoQ8uXb5nQM/4Af4X4=", + "requires": { + "base64-js": "0.0.2", + "to-utf8": "0.0.1" + } + } + } } } } diff --git a/package.json b/package.json index 7af227fad1..62e3ee8e69 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "babel-preset-es2015": "^6.3.13", "babel-preset-react": "^6.3.13", "babel-register": "^6.3.0", + "berkeleys-redux-utils": "^3.2.0", "body-parser": "^1.13.2", "bootstrap": "~3.3.7", "cal-heatmap": "~3.5.2", @@ -65,7 +66,7 @@ "googleapis": "16.1.0", "helmet": "^3.1.0", "helmet-csp": "^2.1.0", - "history": "^3.2.1", + "history": "^4.7.2", "invariant": "^2.2.1", "jade": "^1.11.0", "jquery": "~3.1.1", @@ -99,6 +100,7 @@ "passport-oauth": "^1.0.0", "passport-twitter": "^1.0.3", "pmx": "~0.6.2", + "prop-types": "^15.5.10", "react": "~15.4.2", "react-addons-css-transition-group": "~15.4.2", "react-addons-shallow-compare": "~15.4.2", @@ -112,14 +114,12 @@ "react-notification": "git+https://github.com/BerkeleyTrue/react-notification.git#freecodecamp", "react-pure-render": "^1.0.2", "react-redux": "^4.0.6", - "react-router": "^3.0.0", - "react-router-bootstrap": "~0.23.1", - "react-router-redux": "^4.0.7", "react-youtube": "^7.0.0", "redux": "^3.0.5", "redux-actions": "^2.0.3", "redux-create-types": "0.0.1", "redux-epic": "^0.3.0", + "redux-first-router": "^1.9.19", "redux-form": "^5.2.3", "request": "^2.65.0", "reselect": "^3.0.0", @@ -134,20 +134,18 @@ "devDependencies": { "adler32": "~0.1.7", "babel-cli": "^6.3.17", - "babel-eslint": "^7.0.0", "babel-istanbul": "^0.12.1", "babel-loader": "^6.2.1", "babel-plugin-add-module-exports": "^0.2.1", + "babel-plugin-lodash": "^3.2.11", "babel-preset-stage-0": "^6.3.13", "browser-sync": "^2.9.12", "chunk-manifest-webpack-plugin": "0.1.0", "commitizen": "^2.9.6", "cz-freecodecamp": "^1.0.1", "del": "^2.2.0", - "eslint": "^3.1.0", - "eslint-plugin-import": "^2.0.1", - "eslint-plugin-prefer-object-spread": "^1.1.0", - "eslint-plugin-react": "^6.9.0", + "eslint": "^4.10.0", + "eslint-config-freecodecamp": "^1.1.1", "gulp": "^3.9.0", "gulp-babel": "^6.1.1", "gulp-concat": "^2.6.0", @@ -172,6 +170,7 @@ "merge-stream": "^1.0.0", "proxyquire": "^1.7.10", "react-hot-loader": "^1.3.0", + "remote-redux-devtools": "^0.5.12", "rev-del": "^1.0.5", "sinon": "^2.0.0", "sort-keys": "^1.1.1", diff --git a/seed/challenges/03-front-end-libraries/react.json b/seed/challenges/03-front-end-libraries/react.json index 40d274aee7..c254a3f852 100644 --- a/seed/challenges/03-front-end-libraries/react.json +++ b/seed/challenges/03-front-end-libraries/react.json @@ -6,27 +6,33 @@ "challenges": [ { "id": "587d7dbc367417b2b2512bb1", - "title": "Introduction to the React Challenges", + "title": "Create a Simple JSX Element", "description": [ - [ - "", - "", - "React is a JavaScript library designed to make it easier to build complex user interfaces. React does this in a few ways:

  1. React allows HTML to render from a JavaScript file.
  2. React breaks a website's parts into Components that can then be combined to build pages.
  3. React Components can pass data to each other as properties


React uses a virtual Document Object Model. Instead of changing the DOM directly, React makes a simplified copy of the DOM (the virtual DOM) when the page loads. This allows React to make changes to elements on the page without re-rendering the entire page. This can improve the responsiveness and functionality of single-page applications.

While not part of the React library and not required, JSX is often paired with React. JSX is a preprocessor for JavaScript written in a syntax akin to XML that results in more readable code.

Fun fact: freeCodeCamp is built using React.", - "" - ], - [ - "", - "", - "The React challenges have not been ported into freeCodeCamp yet. You can visit this link to work through the alpha version of these challenges. If you have feedback, you can open an issue (or pull request) directly on this repository.", - "" - ] + "Intro: React is an Open Source view library created and maintained by Facebook. It's a great tool to render the User Interface (UI) of modern web applications.", + "React uses a syntax extension of JavaScript called JSX that allows you to write HTML directly within JavaScript. This has several benefits. It lets you use the full programmatic power of JavaScript within HTML, and helps to keep your code readable. For the most part, JSX is similar to the HTML that you have already learned, however there are a few key differences that will be covered throughout these challenges.", + "For instance, because JSX is a syntactic extension of JavaScript, you can actually write JavaScript directly within JSX. To do this, you simply include the code you want to be treated as JavaScript within curly braces: { 'this is treated as JavaScript code' }. Keep this in mind, since it's used in several future challenges.", + "However, because JSX is not valid JavaScript, JSX code must be compiled into JavaScript. The transpiler Babel is a popular tool for this process. For your convenience, it's already added behind the scenes for these challenges. If you happen to write syntactically invalid JSX, you will see the first test in these challenges fail.", + "
", + "Instructions: The current code uses JSX to assign a div element to the constant JSX. Replace the div with an h1 element and add the text Hello JSX! inside it." ], - "releasedOn": "Feb 17, 2017", - "challengeSeed": [], - "tests": [], - "type": "waypoint", - "challengeType": 7, - "isRequired": false, + "files": { + "indexjsx": { + "key": "indexjxs", + "ext": "jsx", + "name": "index", + "contents": [ + "", + "var jsx =
;", + "" + ] + } + }, + "tests": [ + "assert(Enzyme.shallow(jsx).type === 'h1', 'message: The constant JSX should return an h1 element.');", + "assert(Enzyme.shallow(jsx).children() === 'Hello JSX!', 'message: The h1 tag should include the text Hello JSX!');" + ], + "type": "modern", + "isRequired": true, "translations": {} } ] diff --git a/server/boot/certificate.js b/server/boot/certificate.js index 0b8702858e..1249d8fbdc 100644 --- a/server/boot/certificate.js +++ b/server/boot/certificate.js @@ -73,8 +73,7 @@ function sendCertifiedEmail( username, isFrontEndCert, isBackEndCert, - isDataVisCert, - challengeMap + isDataVisCert }, send$ ) { diff --git a/server/boot/react.js b/server/boot/react.js index be4e86d8c5..83b41692cf 100644 --- a/server/boot/react.js +++ b/server/boot/react.js @@ -1,13 +1,19 @@ -import React from 'react'; -import { RouterContext } from 'react-router'; import debug from 'debug'; -import { renderToString } from 'redux-epic'; - -import createApp from '../../common/app'; -import provideStore from '../../common/app/provide-store'; +import { renderToString } from 'react-dom/server'; +import createMemoryHistory from 'history/createMemoryHistory'; +import { NOT_FOUND } from 'redux-first-router'; +import devtoolsEnhancer from 'remote-redux-devtools'; +import { + loggerMiddleware, + errorThrowerMiddleware +} from '../utils/react.js'; +import { createApp, provideStore, App } from '../../common/app'; +import waitForEpics from '../../common/utils/wait-for-epics.js'; +import { titleSelector } from '../../common/app/redux'; const log = debug('fcc:react-server'); +const isDev = process.env.NODE_ENV !== 'production'; // add routes here as they slowly get reactified // remove their individual controllers @@ -21,6 +27,10 @@ const routes = [ const devRoutes = []; +const middlewares = [ + isDev ? loggerMiddleware : null, + isDev ? errorThrowerMiddleware : null +].filter(Boolean); export default function reactSubRouter(app) { var router = app.loopback.Router(); @@ -48,55 +58,50 @@ export default function reactSubRouter(app) { const serviceOptions = { req }; createApp({ serviceOptions, - location: req.originalUrl, - initialState: { app: { lang } } + middlewares, + enhancers: [ + devtoolsEnhancer({ name: 'server' }) + ], + history: createMemoryHistory({ initialEntries: [ req.originalUrl ] }), + defaultStaet: { app: { lang } } }) - // if react-router does not find a route send down the chain - .filter(({ redirect, props }) => { - if (!props && redirect) { - log('react router found a redirect'); - return res.redirect(redirect.pathname + redirect.search); - } - if (!props) { - log(`react tried to find ${req.path} but got 404`); - return next(); - } - return !!props; - }) - .flatMap(({ props, store, epic }) => { - log('render react markup and pre-fetch data'); - - return renderToString( - provideStore(React.createElement(RouterContext, props), store), - epic - ) - .map(({ markup }) => ({ markup, store, epic })); - }) - .filter(({ store, epic }) => { - const { delayedRedirect } = store.getState().app; - if (delayedRedirect) { - res.redirect(delayedRedirect); - epic.dispose(); + .filter(({ + location: { + type, + kind, + pathname + } = {} + }) => { + if (kind === 'redirect') { + log('react found a redirect'); + res.redirect(pathname); return false; } + + if (type === NOT_FOUND) { + log(`react tried to find ${req.path} but got 404`); + next(); + return false; + } + return true; }) - .flatMap(function({ markup, store, epic }) { + .flatMap(({ store, epic }) => { + return waitForEpics(epic) + .map(() => renderToString( + provideStore(App, store) + )) + .map((markup) => ({ markup, store, epic })); + }) + .do(({ markup, store, epic }) => { log('react markup rendered, data fetched'); const state = store.getState(); - const { title } = state.app; + const title = titleSelector(state); epic.dispose(); - res.expose(state, 'data'); - res.expose(req.flash(), 'flash'); - return res.render$( - 'layout-react', - { markup, title } - ); + res.expose(state, 'data', { isJSON: true }); + res.expose(req.flash(), 'flash', { isJSON: true }); + res.render('layout-react', { markup, title }); }) - .doOnNext(markup => res.send(markup)) - .subscribe( - () => log('html rendered and ready to send'), - next - ); + .subscribe(() => log('html rendered and sent'), next); } } diff --git a/server/utils/react.js b/server/utils/react.js new file mode 100644 index 0000000000..3c6d3299d8 --- /dev/null +++ b/server/utils/react.js @@ -0,0 +1,15 @@ +import debug from 'debug'; + +const log = debug('fcc:server:react:utils'); + +export const errorThrowerMiddleware = () => next => action => { + if (action.error) { + throw action.payload; + } + return next(action); +}; + +export const loggerMiddleware = () => next => action => { + log('action: \n', action); + return next(action); +}; diff --git a/server/utils/user-stats.js b/server/utils/user-stats.js index 228e81ee79..fd33ae6fa0 100644 --- a/server/utils/user-stats.js +++ b/server/utils/user-stats.js @@ -5,12 +5,9 @@ import { dayCount } from '../utils/date-utils'; const daysBetween = 1.5; export function prepUniqueDays(cals, tz = 'UTC') { - - return _(cals) - .map(ts => moment(ts).tz(tz).startOf('day').valueOf()) - .uniq() - .sort() - .value(); + return _.uniq( + _.map(cals, ts => moment(ts).tz(tz).startOf('day').valueOf()) + ).sort(); } export function calcCurrentStreak(cals, tz = 'UTC') {