From 2218194617b727e1800e3c40b372d8b1c2dcb416 Mon Sep 17 00:00:00 2001 From: Ralph Date: Fri, 13 Jul 2018 12:25:23 +0100 Subject: [PATCH 01/24] Added Header and GameContainer components --- package.json | 4 ++-- src/components/App.js | 7 +++++-- src/components/Header.js | 10 ++++++++++ src/containers/GameContainer.js | 16 ++++++++++++++++ 4 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 src/components/Header.js create mode 100644 src/containers/GameContainer.js diff --git a/package.json b/package.json index 7102a0e..149d2ba 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "index.js", "scripts": { "test": "jest", - "dev": "webpack --mode development", + "dev": "webpack --mode development --watch", "build": "webpack --mode production" }, "author": "", @@ -37,4 +37,4 @@ "webpack": "^4.0.1", "webpack-cli": "^2.0.9" } -} +} \ No newline at end of file diff --git a/src/components/App.js b/src/components/App.js index ef2abb3..b859b27 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -1,10 +1,13 @@ import React from 'react'; +import Header from './Header'; +import GameContainer from '../containers/GameContainer' class App extends React.Component { - render(){ + render() { return (
- App contents go here +
+
) } diff --git a/src/components/Header.js b/src/components/Header.js new file mode 100644 index 0000000..f76b89f --- /dev/null +++ b/src/components/Header.js @@ -0,0 +1,10 @@ +import React from 'react'; + +function Header() { + return ( +
+

QuizMachine

+
+ ); +} +export default Header; \ No newline at end of file diff --git a/src/containers/GameContainer.js b/src/containers/GameContainer.js new file mode 100644 index 0000000..8f79cec --- /dev/null +++ b/src/containers/GameContainer.js @@ -0,0 +1,16 @@ +import React from 'react'; + +class GameContainer extends React.Component { + constructor(props) { + super(props); + } + + render() { + return ( +
Game goes here
+ ) + + } +} + +export default GameContainer; \ No newline at end of file From da57c3c7fe5276a5ba3fc3eec686643faddb4039 Mon Sep 17 00:00:00 2001 From: Ralph Date: Fri, 13 Jul 2018 15:50:14 +0100 Subject: [PATCH 02/24] Added Question component --- index.html | 25 +- package-lock.json | 1051 +++++++++++++++++++++++++-- package.json | 6 +- src/actions/index.js | 19 +- src/components/App.js | 8 +- src/components/Header.js | 1 + src/components/Question.js | 34 + src/containers/GameContainer.js | 16 - src/containers/QuestionContainer.js | 20 + src/reducers/index.js | 4 +- src/reducers/placeholder.js | 8 - src/reducers/quizQuestion.js | 10 + src/static/styles/_layout.scss | 5 + src/static/styles/header.scss | 3 + src/static/styles/style.scss | 1 + style.css | 15 - webpack.config.js | 12 + 17 files changed, 1133 insertions(+), 105 deletions(-) create mode 100644 src/components/Question.js delete mode 100644 src/containers/GameContainer.js create mode 100644 src/containers/QuestionContainer.js delete mode 100644 src/reducers/placeholder.js create mode 100644 src/reducers/quizQuestion.js create mode 100644 src/static/styles/_layout.scss create mode 100644 src/static/styles/header.scss create mode 100644 src/static/styles/style.scss diff --git a/index.html b/index.html index 20c7415..262adbe 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,16 @@ - - Redux intro - - - -
- -
- - - + + + Quiz Machine + + + + +
+ +
+ + + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 90154a0..b3f8dea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -362,6 +362,12 @@ "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=", "dev": true }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, "acorn": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", @@ -481,6 +487,16 @@ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -520,6 +536,12 @@ "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", "dev": true }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", @@ -634,6 +656,12 @@ "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", "dev": true }, + "async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", + "dev": true + }, "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", @@ -1750,6 +1778,15 @@ "integrity": "sha512-XBaoWE9RW8pPdPQNibZsW2zh8TW6gcarXp1FZPwT8Uop8ScSNldJEWf2k9l3HeTqdrEwsOsFcq74RiJECW34yA==", "dev": true }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "dev": true, + "requires": { + "inherits": "~2.0.0" + } + }, "bluebird": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", @@ -1767,6 +1804,15 @@ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, + "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.x.x" + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2040,6 +2086,24 @@ "dev": true, "optional": true }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + } + } + }, "caniuse-lite": { "version": "1.0.30000865", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000865.tgz", @@ -2325,6 +2389,29 @@ "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", "dev": true }, + "clone-deep": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz", + "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==", + "dev": true, + "requires": { + "for-own": "^1.0.0", + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.0", + "shallow-clone": "^1.0.0" + }, + "dependencies": { + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + } + } + }, "clone-response": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", @@ -2453,6 +2540,12 @@ "date-now": "^0.1.4" } }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", @@ -2543,6 +2636,15 @@ "which": "^1.2.9" } }, + "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.x.x" + } + }, "crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", @@ -2562,6 +2664,26 @@ "randomfill": "^1.0.3" } }, + "css-loader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-1.0.0.tgz", + "integrity": "sha512-tMXlTYf3mIMt3b0dDCOQFJiVvxbocJ5Ho577WiGPYPZcqVEO218L2iU22pDXzkTZCLDE+9AmGSUkWxeh/nZReA==", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "css-selector-tokenizer": "^0.7.0", + "icss-utils": "^2.1.0", + "loader-utils": "^1.0.2", + "lodash.camelcase": "^4.3.0", + "postcss": "^6.0.23", + "postcss-modules-extract-imports": "^1.2.0", + "postcss-modules-local-by-default": "^1.2.0", + "postcss-modules-scope": "^1.1.0", + "postcss-modules-values": "^1.3.0", + "postcss-value-parser": "^3.3.0", + "source-list-map": "^2.0.0" + } + }, "css-select": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", @@ -2573,11 +2695,41 @@ "nth-check": "~1.0.1" } }, + "css-selector-tokenizer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz", + "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=", + "dev": true, + "requires": { + "cssesc": "^0.1.0", + "fastparse": "^1.1.1", + "regexpu-core": "^1.0.0" + }, + "dependencies": { + "regexpu-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", + "dev": true, + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + } + } + }, "css-what": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=" }, + "cssesc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", + "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=", + "dev": true + }, "cssom": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.4.tgz", @@ -2593,6 +2745,15 @@ "cssom": "0.3.x" } }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, "cyclist": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", @@ -2758,6 +2919,12 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, "des.js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", @@ -3521,6 +3688,12 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fastparse": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz", + "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=", + "dev": true + }, "fb-watchman": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", @@ -4240,6 +4413,18 @@ } } }, + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -4255,12 +4440,65 @@ "is-callable": "^1.1.3" } }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "dev": true, + "requires": { + "globule": "^1.0.0" + } + }, "get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", "dev": true }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", @@ -4474,6 +4712,17 @@ } } }, + "globule": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz", + "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==", + "dev": true, + "requires": { + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" + } + }, "got": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", @@ -4622,6 +4871,12 @@ "has-symbol-support-x": "^1.4.1" } }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -4674,6 +4929,18 @@ "minimalistic-assert": "^1.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.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" + } + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -4685,6 +4952,12 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, "hoist-non-react-statics": { "version": "2.5.5", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", @@ -4768,6 +5041,21 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", + "dev": true + }, + "icss-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz", + "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", + "dev": true, + "requires": { + "postcss": "^6.0.1" + } + }, "ieee754": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", @@ -4802,6 +5090,12 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, + "in-publish": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", + "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=", + "dev": true + }, "indent-string": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", @@ -6430,6 +6724,12 @@ "merge-stream": "^1.0.1" } }, + "js-base64": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.6.tgz", + "integrity": "sha512-O9SR2NVICx6rCqh1qsU91QZ5IoNa+2T1ROJ0OQlfvATKGmnjsAvg3r0E5ufPZ4a95jdKTPXhFWiE/sOZ7a5Rtg==", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -6979,6 +7279,24 @@ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.10.tgz", "integrity": "sha512-iesFYPmxYYGTcmQK0sL8bX3TGHyM6b2qREaB4kamHfQyfPJP0xgoGxp19nsH16nsfquLdiyKyX3mQkfiSGV8Rg==" }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", + "dev": true + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -6990,12 +7308,24 @@ "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" }, + "lodash.mergewith": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", + "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", + "dev": true + }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, + "lodash.tail": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz", + "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=", + "dev": true + }, "log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", @@ -7099,6 +7429,16 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -7153,6 +7493,12 @@ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", @@ -7281,6 +7627,32 @@ "readable-stream": "^2.0.1" } }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, "merge": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz", @@ -7426,6 +7798,24 @@ } } }, + "mixin-object": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", + "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=", + "dev": true, + "requires": { + "for-in": "^0.1.3", + "is-extendable": "^0.1.1" + }, + "dependencies": { + "for-in": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz", + "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=", + "dev": true + } + } + }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", @@ -7477,8 +7867,7 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true, - "optional": true + "dev": true }, "nanomatch": { "version": "1.2.13", @@ -7543,56 +7932,201 @@ "is-stream": "^1.0.1" } }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", - "dev": true - }, - "node-libs-browser": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", - "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", + "node-gyp": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.7.0.tgz", + "integrity": "sha512-qDQE/Ft9xXP6zphwx4sD0t+VhwV7yFaloMpfbL2QnnDZcyaiakWlLdtFGGQfTAwpFHdpbRhRxVhIHN1OKAjgbg==", "dev": true, "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^1.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.0", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.10.3", - "vm-browserify": "0.0.4" + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": ">=2.9.0 <2.82.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" }, "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "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 - } - } - }, - "node-notifier": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.2.1.tgz", - "integrity": "sha512-MIBs+AAd6dJ2SklbbE8RUDRlIVhU8MaNLh1A9SUZDUHPiZkWLFde6UNwG41yQHZEToHgJMXqyVZ9UcS/ReOVTg==", - "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 + }, + "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.12" + } + }, + "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 + }, + "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.9.1", + "har-schema": "^1.0.5" + } + }, + "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.2.2", + "sshpk": "^1.7.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 + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "qs": { + "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.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.2.1", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~2.1.1", + "har-validator": "~4.2.1", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "oauth-sign": "~0.8.1", + "performance-now": "^0.2.0", + "qs": "~6.4.0", + "safe-buffer": "^5.0.1", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.0.0" + } + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + }, + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "dev": true, + "requires": { + "punycode": "^1.4.1" + } + } + } + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-libs-browser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", + "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^1.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.0", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.10.3", + "vm-browserify": "0.0.4" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "node-notifier": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.2.1.tgz", + "integrity": "sha512-MIBs+AAd6dJ2SklbbE8RUDRlIVhU8MaNLh1A9SUZDUHPiZkWLFde6UNwG41yQHZEToHgJMXqyVZ9UcS/ReOVTg==", + "dev": true, "requires": { "growly": "^1.3.0", "semver": "^5.4.1", @@ -7600,6 +8134,45 @@ "which": "^1.3.0" } }, + "node-sass": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.9.2.tgz", + "integrity": "sha512-LdxoJLZutx0aQXHtWIYwJKMj+9pTjneTcLWJgzf2XbGu0q5pRNqW5QvFCEdm3mc5rJOdru/mzln5d0EZLacf6g==", + "dev": true, + "requires": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^3.0.0", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "in-publish": "^2.0.0", + "lodash.assign": "^4.2.0", + "lodash.clonedeep": "^4.3.2", + "lodash.mergewith": "^4.6.0", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.10.0", + "node-gyp": "^3.3.1", + "npmlog": "^4.0.0", + "request": "2.87.0", + "sass-graph": "^2.2.4", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" + }, + "dependencies": { + "cross-spawn": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + } + } + }, "nomnom": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.6.2.tgz", @@ -7609,6 +8182,15 @@ "underscore": "~1.4.4" } }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, "normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", @@ -7650,6 +8232,18 @@ "path-key": "^2.0.0" } }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, "nth-check": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", @@ -7916,6 +8510,16 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, "p-cancelable": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", @@ -8172,6 +8776,99 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-modules-extract-imports": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.0.tgz", + "integrity": "sha1-ZhQOzs447wa/DT41XWm/WdFB6oU=", + "dev": true, + "requires": { + "postcss": "^6.0.1" + } + }, + "postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", + "dev": true, + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", + "dev": true, + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", + "dev": true, + "requires": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^6.0.1" + } + }, + "postcss-value-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", + "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=", + "dev": true + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -8602,6 +9299,16 @@ "resolve": "^1.1.6" } }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, "redux": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.0.tgz", @@ -8986,6 +9693,123 @@ } } }, + "sass-graph": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", + "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", + "dev": true, + "requires": { + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^7.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.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" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "yargs": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", + "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "dev": true, + "requires": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^5.0.0" + } + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "dev": true, + "requires": { + "camelcase": "^3.0.0" + } + } + } + }, + "sass-loader": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.0.3.tgz", + "integrity": "sha512-iaSFtQcGo4SSgDw5Aes5p4VTrA5jCGSA7sGmhPIcOloBlgI1VktM2MUrk2IHHjbNagckXlPz+HWq1vAAPrcYxA==", + "dev": true, + "requires": { + "clone-deep": "^2.0.1", + "loader-utils": "^1.0.1", + "lodash.tail": "^4.1.1", + "neo-async": "^2.5.0", + "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 + } + } + }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -9034,6 +9858,27 @@ "integrity": "sha1-o0a7Gs1CB65wvXwMfKnlZra63bg=", "dev": true }, + "scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "dev": true, + "requires": { + "js-base64": "^2.1.8", + "source-map": "^0.4.2" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", @@ -9095,6 +9940,25 @@ "safe-buffer": "^5.0.1" } }, + "shallow-clone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz", + "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==", + "dev": true, + "requires": { + "is-extendable": "^0.1.1", + "kind-of": "^5.0.0", + "mixin-object": "^2.0.1" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -9258,6 +10122,15 @@ } } }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "requires": { + "hoek": "2.x.x" + } + }, "sort-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", @@ -9416,6 +10289,15 @@ } } }, + "stdout-stream": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz", + "integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, "stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", @@ -9535,6 +10417,12 @@ "safe-buffer": "~5.1.0" } }, + "stringstream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", + "dev": true + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -9569,6 +10457,25 @@ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1" + } + }, + "style-loader": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.21.0.tgz", + "integrity": "sha512-T+UNsAcl3Yg+BsPKs1vd22Fr8sVT+CJMtzqc6LEw9bbJZb43lm9GoeIfUcDEefBSWC0BhYbcdupV1GtI4DGzxg==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "schema-utils": "^0.4.5" + } + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -9592,6 +10499,17 @@ "integrity": "sha512-dQRhbNQkRnaqauC7WqSJ21EEksgT0fYZX2lqXzGkpo8JNig9zGZTYoMGvyI2nWmXlE2VSVXVDu7wLVGu/mQEsg==", "dev": true }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "dev": true, + "requires": { + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" + } + }, "temp": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", @@ -9768,12 +10686,42 @@ "punycode": "^2.1.0" } }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, "trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, + "true-case-path": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.2.tgz", + "integrity": "sha1-fskRMJJHZsf1c74wIMNPj9/QDWI=", + "dev": true, + "requires": { + "glob": "^6.0.4" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, "tslib": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", @@ -10669,6 +11617,15 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, "window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", diff --git a/package.json b/package.json index 149d2ba..c7bc104 100644 --- a/package.json +++ b/package.json @@ -32,9 +32,13 @@ "babel-loader": "^7.1.3", "babel-preset-env": "^1.6.1", "babel-preset-react": "^6.24.1", + "css-loader": "^1.0.0", "jest": "^22.4.2", + "node-sass": "^4.9.2", "react-test-renderer": "^16.4.1", + "sass-loader": "^7.0.3", + "style-loader": "^0.21.0", "webpack": "^4.0.1", "webpack-cli": "^2.0.9" } -} \ No newline at end of file +} diff --git a/src/actions/index.js b/src/actions/index.js index a1d9430..a32421b 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -1,5 +1,20 @@ -export function fetchQuestion(){ - return function(dispatch){ +export function receiveQuestion(result) { + return { + type: 'RECEIVE_QUESTION', + quizQuestion: result } } + +export function fetchQuestion() { + return function (dispatch) { + fetch(`https://opentdb.com/api.php?amount=1&type=multiple`) + .then(response => response.json()) + .then(result => { + dispatch(receiveQuestion(result)); + }) + .catch(function (error) { + console.log(error); + }); + } +} \ No newline at end of file diff --git a/src/components/App.js b/src/components/App.js index b859b27..748fd86 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -1,13 +1,15 @@ import React from 'react'; import Header from './Header'; -import GameContainer from '../containers/GameContainer' +import QuestionContainer from '../containers/QuestionContainer'; + +import '../static/styles/style.scss'; class App extends React.Component { render() { return ( -
+
- +
) } diff --git a/src/components/Header.js b/src/components/Header.js index f76b89f..2d1ab85 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -1,4 +1,5 @@ import React from 'react'; +import '../static/styles/header.scss'; function Header() { return ( diff --git a/src/components/Question.js b/src/components/Question.js new file mode 100644 index 0000000..178b6bf --- /dev/null +++ b/src/components/Question.js @@ -0,0 +1,34 @@ +import React from 'react'; + +class Question extends React.Component { + constructor(props) { + super(props); + this.createQuestionMarkup = this.createQuestionMarkup.bind(this); + } + + componentDidMount() { + this.props.requestQuestion(); + } + + createQuestionMarkup(question) { + return { __html: question }; + }; + + render() { + const { quizQuestion } = this.props; + return ( +
+ {quizQuestion + ? quizQuestion.results.map(result => { + // + return

+ }) + : "" + + } +

+ ) + } +} + +export default Question; diff --git a/src/containers/GameContainer.js b/src/containers/GameContainer.js deleted file mode 100644 index 8f79cec..0000000 --- a/src/containers/GameContainer.js +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react'; - -class GameContainer extends React.Component { - constructor(props) { - super(props); - } - - render() { - return ( -
Game goes here
- ) - - } -} - -export default GameContainer; \ No newline at end of file diff --git a/src/containers/QuestionContainer.js b/src/containers/QuestionContainer.js new file mode 100644 index 0000000..6abbd76 --- /dev/null +++ b/src/containers/QuestionContainer.js @@ -0,0 +1,20 @@ +import { connect } from 'react-redux' +import Question from '../components/Question'; +import { fetchQuestion } from '../actions'; + +export const mapStateToProps = reduxStore => { + return { + quizQuestion: reduxStore.quizQuestion + }; +}; + +const mapDispatchToProps = dispatch => { + return { + requestQuestion: () => dispatch(fetchQuestion()) + } +}; + +export default connect( + mapStateToProps, + mapDispatchToProps +)(Question); \ No newline at end of file diff --git a/src/reducers/index.js b/src/reducers/index.js index 8e738e8..f450a26 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -1,6 +1,6 @@ import { combineReducers } from 'redux'; -import placeholder from './placeholder'; +import quizQuestion from './quizQuestion'; export default combineReducers({ - placeholder + quizQuestion }); diff --git a/src/reducers/placeholder.js b/src/reducers/placeholder.js deleted file mode 100644 index 25755c5..0000000 --- a/src/reducers/placeholder.js +++ /dev/null @@ -1,8 +0,0 @@ -function placeholder(state = '', action){ - switch (action.type) { - default: - return state - } -} - -export default placeholder; diff --git a/src/reducers/quizQuestion.js b/src/reducers/quizQuestion.js new file mode 100644 index 0000000..3f28e1c --- /dev/null +++ b/src/reducers/quizQuestion.js @@ -0,0 +1,10 @@ +function quizQuestion(state = '', action) { + switch (action.type) { + case 'RECEIVE_QUESTION': + return action.quizQuestion + default: + return state + } +} + +export default quizQuestion; diff --git a/src/static/styles/_layout.scss b/src/static/styles/_layout.scss new file mode 100644 index 0000000..1b2b69d --- /dev/null +++ b/src/static/styles/_layout.scss @@ -0,0 +1,5 @@ +.quiz-wrapper { + width: 1200px; + max-width: 100%; + margin: 0 auto; +} \ No newline at end of file diff --git a/src/static/styles/header.scss b/src/static/styles/header.scss new file mode 100644 index 0000000..acbbda4 --- /dev/null +++ b/src/static/styles/header.scss @@ -0,0 +1,3 @@ +h1 { + color: pink; +} \ No newline at end of file diff --git a/src/static/styles/style.scss b/src/static/styles/style.scss new file mode 100644 index 0000000..66d329a --- /dev/null +++ b/src/static/styles/style.scss @@ -0,0 +1 @@ +@import './layout' \ No newline at end of file diff --git a/style.css b/style.css index d9bbbe0..e69de29 100644 --- a/style.css +++ b/style.css @@ -1,15 +0,0 @@ -.voting-button { - color: #550527; - font-size: 24px; - padding: 10px; - margin: 10px; - border-radius: 5px; - background-color: white; - border: 2px solid #550527; -} - -.voting-button--selected { - color: #FFF; - background-color: #550527; - border: 2px solid white; -} diff --git a/webpack.config.js b/webpack.config.js index 9355dc3..535a579 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -13,6 +13,18 @@ module.exports = { test: /\.js$/, exclude: /(node_modules)/, loader: require.resolve('babel-loader') + }, + { + test: /\.scss$/, + use: [ + { + loader: "style-loader" + }, { + loader: "css-loader" + }, { + loader: "sass-loader" + } + ] } ] } From 174c35814a7f75255795d4924539eec54ff3cc1a Mon Sep 17 00:00:00 2001 From: Ralph Date: Fri, 13 Jul 2018 16:37:20 +0100 Subject: [PATCH 03/24] Added Answers component --- src/components/Answers.js | 35 ++++++++++++++++++++++++++++++ src/components/App.js | 2 ++ src/containers/AnswersContainer.js | 20 +++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 src/components/Answers.js create mode 100644 src/containers/AnswersContainer.js diff --git a/src/components/Answers.js b/src/components/Answers.js new file mode 100644 index 0000000..2c6c3e1 --- /dev/null +++ b/src/components/Answers.js @@ -0,0 +1,35 @@ +import React from 'react'; + +class Answers extends React.Component { + constructor(props) { + super(props); + this.createQuestionMarkup = this.createQuestionMarkup.bind(this); + } + + // componentDidMount() { + // this.props.requestQuestion(); + // } + + createQuestionMarkup(question) { + return { __html: question }; + }; + + render() { + const { answers } = this.props; + const question_answers = answers + ? [...answers.results[0].incorrect_answers, answers.results[0].correct_answer] + : []; + + const shuffled_questions = question_answers.sort(() => 0.5 - Math.random()); + + return ( +
+ {shuffled_questions.map(answer => { + return
+ ) + } +} + +export default Answers; diff --git a/src/components/App.js b/src/components/App.js index 748fd86..0d42d12 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -1,6 +1,7 @@ import React from 'react'; import Header from './Header'; import QuestionContainer from '../containers/QuestionContainer'; +import AnswersContainer from '../containers/AnswersContainer'; import '../static/styles/style.scss'; @@ -10,6 +11,7 @@ class App extends React.Component {
+
) } diff --git a/src/containers/AnswersContainer.js b/src/containers/AnswersContainer.js new file mode 100644 index 0000000..775f3d0 --- /dev/null +++ b/src/containers/AnswersContainer.js @@ -0,0 +1,20 @@ +import { connect } from 'react-redux' +import Answers from '../components/Answers'; +// import { fetchQuestion } from '../actions'; + +export const mapStateToProps = reduxStore => { + return { + answers: reduxStore.quizQuestion + }; +}; + +// const mapDispatchToProps = dispatch => { +// return { +// requestQuestion: () => dispatch(fetchQuestion()) +// } +// }; + +export default connect( + mapStateToProps, + null +)(Answers); \ No newline at end of file From d6493e0ae7d7ed65c773db525645975f3df9c9ab Mon Sep 17 00:00:00 2001 From: Ralph Date: Fri, 13 Jul 2018 17:06:56 +0100 Subject: [PATCH 04/24] Refactor to functional Answers component --- src/components/Answers.js | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/src/components/Answers.js b/src/components/Answers.js index 2c6c3e1..cc02c97 100644 --- a/src/components/Answers.js +++ b/src/components/Answers.js @@ -1,35 +1,22 @@ import React from 'react'; -class Answers extends React.Component { - constructor(props) { - super(props); - this.createQuestionMarkup = this.createQuestionMarkup.bind(this); - } +function Answers({ answers }) { - // componentDidMount() { - // this.props.requestQuestion(); - // } - - createQuestionMarkup(question) { + function createQuestionMarkup(question) { return { __html: question }; }; - render() { - const { answers } = this.props; - const question_answers = answers - ? [...answers.results[0].incorrect_answers, answers.results[0].correct_answer] - : []; - - const shuffled_questions = question_answers.sort(() => 0.5 - Math.random()); - - return ( -
- {shuffled_questions.map(answer => { - return
- ) - } + const question_answers = answers + ? [...answers.results[0].incorrect_answers, answers.results[0].correct_answer] + : []; + const shuffled_questions = question_answers.sort(() => 0.5 - Math.random()); + return ( +
+ {shuffled_questions.map(answer => { + return
+ ) } export default Answers; From afa752f7fd19a968047907bbd47d5149f33a80e2 Mon Sep 17 00:00:00 2001 From: Ralph Date: Fri, 13 Jul 2018 20:05:03 +0100 Subject: [PATCH 05/24] Verify answer --- src/actions/index.js | 7 +++++++ src/components/Answers.js | 29 +++++++++++++++++++++++------ src/containers/AnswersContainer.js | 14 +++++++------- src/reducers/answer.js | 10 ++++++++++ 4 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 src/reducers/answer.js diff --git a/src/actions/index.js b/src/actions/index.js index a32421b..51b3690 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -6,6 +6,13 @@ export function receiveQuestion(result) { } } +export function isRightAnswer(questionAnswer) { + return { + type: 'RECEIVE_ANSWER', + questionAnswer + } +} + export function fetchQuestion() { return function (dispatch) { fetch(`https://opentdb.com/api.php?amount=1&type=multiple`) diff --git a/src/components/Answers.js b/src/components/Answers.js index cc02c97..1bc4e33 100644 --- a/src/components/Answers.js +++ b/src/components/Answers.js @@ -1,19 +1,36 @@ import React from 'react'; -function Answers({ answers }) { +function Answers({ answers, isRightAnswer }) { - function createQuestionMarkup(question) { - return { __html: question }; + function createAnswerMarkup(answer) { + return { __html: answer }; }; const question_answers = answers ? [...answers.results[0].incorrect_answers, answers.results[0].correct_answer] : []; - const shuffled_questions = question_answers.sort(() => 0.5 - Math.random()); + const shuffled_answers = question_answers.sort(() => 0.5 - Math.random()); + + function verifyAnswer(answer) { + if (answer === answers.results[0].correct_answer) { + // console.log(answers.results[0].correct_answer); + // console.log(answer); + console.log("Right!"); + isRightAnswer(true); + } else { + // console.log(answers.results[0].correct_answer); + // console.log(answer); + console.log("Wrong!"); + isRightAnswer(false); + } + } return (
- {shuffled_questions.map(answer => { - return
) diff --git a/src/containers/AnswersContainer.js b/src/containers/AnswersContainer.js index 775f3d0..75ac06e 100644 --- a/src/containers/AnswersContainer.js +++ b/src/containers/AnswersContainer.js @@ -1,6 +1,6 @@ import { connect } from 'react-redux' import Answers from '../components/Answers'; -// import { fetchQuestion } from '../actions'; +import { isRightAnswer } from '../actions'; export const mapStateToProps = reduxStore => { return { @@ -8,13 +8,13 @@ export const mapStateToProps = reduxStore => { }; }; -// const mapDispatchToProps = dispatch => { -// return { -// requestQuestion: () => dispatch(fetchQuestion()) -// } -// }; +const mapDispatchToProps = dispatch => { + return { + isRightAnswer: isRight => dispatch(isRightAnswer(isRight)) + } +}; export default connect( mapStateToProps, - null + mapDispatchToProps )(Answers); \ No newline at end of file diff --git a/src/reducers/answer.js b/src/reducers/answer.js new file mode 100644 index 0000000..4ddbcc5 --- /dev/null +++ b/src/reducers/answer.js @@ -0,0 +1,10 @@ +function quizAnswer(state = '', action) { + switch (action.type) { + case 'RECEIVE_QUESTION': + return action.questionAnswer + default: + return state + } +} + +export default quizQuestion; \ No newline at end of file From 6e55cf3384e143c65ed1cfbfb45021ae72d751b6 Mon Sep 17 00:00:00 2001 From: Ralph Date: Fri, 13 Jul 2018 21:17:30 +0100 Subject: [PATCH 06/24] Added Message component --- src/components/App.js | 2 ++ src/components/Message.js | 9 +++++++++ src/containers/MessageContainer.js | 14 ++++++++++++++ src/reducers/index.js | 4 +++- src/reducers/{answer.js => quizAnswer.js} | 4 ++-- 5 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 src/components/Message.js create mode 100644 src/containers/MessageContainer.js rename src/reducers/{answer.js => quizAnswer.js} (72%) diff --git a/src/components/App.js b/src/components/App.js index 0d42d12..3a6106a 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -2,6 +2,7 @@ import React from 'react'; import Header from './Header'; import QuestionContainer from '../containers/QuestionContainer'; import AnswersContainer from '../containers/AnswersContainer'; +import MessageContainer from '../containers/MessageContainer'; import '../static/styles/style.scss'; @@ -12,6 +13,7 @@ class App extends React.Component {
+
) } diff --git a/src/components/Message.js b/src/components/Message.js new file mode 100644 index 0000000..fb5822d --- /dev/null +++ b/src/components/Message.js @@ -0,0 +1,9 @@ +import React from 'react'; + +function Message({ questionAnswer }) { + return ( +
{questionAnswer ? "Right!" : ""}
+ ); +} + +export default Message; \ No newline at end of file diff --git a/src/containers/MessageContainer.js b/src/containers/MessageContainer.js new file mode 100644 index 0000000..51bccb4 --- /dev/null +++ b/src/containers/MessageContainer.js @@ -0,0 +1,14 @@ +import React from 'react'; +import { connect } from 'react-redux'; +import Message from '../components/Message'; + +export const mapStateToProps = reduxStore => { + return { + questionAnswer: reduxStore.quizAnswer + } +} + +export default connect( + mapStateToProps, + null +)(Message); \ No newline at end of file diff --git a/src/reducers/index.js b/src/reducers/index.js index f450a26..70e9953 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -1,6 +1,8 @@ import { combineReducers } from 'redux'; import quizQuestion from './quizQuestion'; +import quizAnswer from './quizAnswer'; export default combineReducers({ - quizQuestion + quizQuestion, + quizAnswer }); diff --git a/src/reducers/answer.js b/src/reducers/quizAnswer.js similarity index 72% rename from src/reducers/answer.js rename to src/reducers/quizAnswer.js index 4ddbcc5..9135ad9 100644 --- a/src/reducers/answer.js +++ b/src/reducers/quizAnswer.js @@ -1,10 +1,10 @@ function quizAnswer(state = '', action) { switch (action.type) { - case 'RECEIVE_QUESTION': + case 'RECEIVE_ANSWER': return action.questionAnswer default: return state } } -export default quizQuestion; \ No newline at end of file +export default quizAnswer; \ No newline at end of file From f6b1b344fc7bf2bc760e9d457c1dca9fb6c1abb7 Mon Sep 17 00:00:00 2001 From: Ralph Date: Sat, 14 Jul 2018 13:52:05 +0100 Subject: [PATCH 07/24] Added ButtonNext component --- src/actions/index.js | 2 +- src/components/Answers.js | 14 ++++---------- src/components/App.js | 2 ++ src/components/ButtonNext.js | 11 +++++++++++ src/components/Question.js | 25 +++++++++++-------------- src/containers/ButtonNextContainer.js | 15 +++++++++++++++ 6 files changed, 44 insertions(+), 25 deletions(-) create mode 100644 src/components/ButtonNext.js create mode 100644 src/containers/ButtonNextContainer.js diff --git a/src/actions/index.js b/src/actions/index.js index 51b3690..52f6ced 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -15,7 +15,7 @@ export function isRightAnswer(questionAnswer) { export function fetchQuestion() { return function (dispatch) { - fetch(`https://opentdb.com/api.php?amount=1&type=multiple`) + fetch(`https://opentdb.com/api.php?amount=1&type=multiple&encode=url3986`) .then(response => response.json()) .then(result => { dispatch(receiveQuestion(result)); diff --git a/src/components/Answers.js b/src/components/Answers.js index 1bc4e33..9278938 100644 --- a/src/components/Answers.js +++ b/src/components/Answers.js @@ -2,24 +2,17 @@ import React from 'react'; function Answers({ answers, isRightAnswer }) { - function createAnswerMarkup(answer) { - return { __html: answer }; - }; - const question_answers = answers ? [...answers.results[0].incorrect_answers, answers.results[0].correct_answer] : []; + const shuffled_answers = question_answers.sort(() => 0.5 - Math.random()); function verifyAnswer(answer) { if (answer === answers.results[0].correct_answer) { - // console.log(answers.results[0].correct_answer); - // console.log(answer); console.log("Right!"); isRightAnswer(true); } else { - // console.log(answers.results[0].correct_answer); - // console.log(answer); console.log("Wrong!"); isRightAnswer(false); } @@ -29,8 +22,9 @@ function Answers({ answers, isRightAnswer }) { {shuffled_answers.map(answer => { return })} ) diff --git a/src/components/App.js b/src/components/App.js index 3a6106a..2f4b6e1 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -3,6 +3,7 @@ import Header from './Header'; import QuestionContainer from '../containers/QuestionContainer'; import AnswersContainer from '../containers/AnswersContainer'; import MessageContainer from '../containers/MessageContainer'; +import ButtonNextContainer from '../containers/ButtonNextContainer'; import '../static/styles/style.scss'; @@ -14,6 +15,7 @@ class App extends React.Component { + ) } diff --git a/src/components/ButtonNext.js b/src/components/ButtonNext.js new file mode 100644 index 0000000..eafbf40 --- /dev/null +++ b/src/components/ButtonNext.js @@ -0,0 +1,11 @@ +import React from 'react'; +function ButtonNext({ requestQuestion, isRightAnswer }) { + return ( + + ); +} + +export default ButtonNext; \ No newline at end of file diff --git a/src/components/Question.js b/src/components/Question.js index 178b6bf..a54683a 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -3,32 +3,29 @@ import React from 'react'; class Question extends React.Component { constructor(props) { super(props); - this.createQuestionMarkup = this.createQuestionMarkup.bind(this); } componentDidMount() { this.props.requestQuestion(); } - createQuestionMarkup(question) { - return { __html: question }; - }; - render() { const { quizQuestion } = this.props; return (
- {quizQuestion - ? quizQuestion.results.map(result => { - // - return

- }) - : "" + { + quizQuestion + ? quizQuestion.results.map(result => { + return

+ {decodeURIComponent(result.question)} +

+ + }) + : "" }
- ) - } + ); + }; } - export default Question; diff --git a/src/containers/ButtonNextContainer.js b/src/containers/ButtonNextContainer.js new file mode 100644 index 0000000..0c667f9 --- /dev/null +++ b/src/containers/ButtonNextContainer.js @@ -0,0 +1,15 @@ +import { connect } from 'react-redux' +import ButtonNext from '../components/ButtonNext'; +import { fetchQuestion, isRightAnswer } from '../actions'; + +const mapDispatchToProps = dispatch => { + return { + isRightAnswer: isRight => dispatch(isRightAnswer(isRight)), + requestQuestion: () => dispatch(fetchQuestion()) + } +}; + +export default connect( + null, + mapDispatchToProps +)(ButtonNext); \ No newline at end of file From 4dea54e1c11e858b07dcbbcbebaf3b7e056ffe97 Mon Sep 17 00:00:00 2001 From: Ralph Date: Sat, 14 Jul 2018 20:28:52 +0100 Subject: [PATCH 08/24] Added points --- src/actions/index.js | 42 ++++++++++++++++++++++++------ src/components/Answers.js | 16 +++++++++--- src/components/App.js | 2 ++ src/components/Score.js | 9 +++++++ src/containers/AnswersContainer.js | 6 +++-- src/containers/ScoreContainer.js | 21 +++++++++++++++ src/reducers/index.js | 4 ++- src/reducers/score.js | 10 +++++++ 8 files changed, 95 insertions(+), 15 deletions(-) create mode 100644 src/components/Score.js create mode 100644 src/containers/ScoreContainer.js create mode 100644 src/reducers/score.js diff --git a/src/actions/index.js b/src/actions/index.js index 52f6ced..42d8fea 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -13,15 +13,41 @@ export function isRightAnswer(questionAnswer) { } } +export function scoreUpdate(score) { + return { + type: 'RECEIVE_SCORE', + score + } +} + export function fetchQuestion() { return function (dispatch) { - fetch(`https://opentdb.com/api.php?amount=1&type=multiple&encode=url3986`) - .then(response => response.json()) - .then(result => { - dispatch(receiveQuestion(result)); - }) - .catch(function (error) { - console.log(error); - }); + dispatch(receiveQuestion({ + + "response_code": 0, + "results": [ + { + "category": "Entertainment: Television", + "type": "multiple", + "difficulty": "medium", + "question": "In Star Trek, what is the Ferengi's First Rule of Acquisition?", + "correct_answer": "Once you have their money, you never give it back. ", + "incorrect_answers": [ + "Never place friendship above profit", + "Greed is Eternal", + "Never allow family to stand in the way of opportunity" + ] + } + ] + + })); + // fetch(`https://opentdb.com/api.php?amount=1&type=multiple&encode=url3986`) + // .then(response => response.json()) + // .then(result => { + // dispatch(receiveQuestion(result)); + // }) + // .catch(function (error) { + // console.log(error); + // }); } } \ No newline at end of file diff --git a/src/components/Answers.js b/src/components/Answers.js index 9278938..7566f26 100644 --- a/src/components/Answers.js +++ b/src/components/Answers.js @@ -1,6 +1,7 @@ import React from 'react'; +import cx from 'classnames'; -function Answers({ answers, isRightAnswer }) { +function Answers({ answers, isRightAnswer, score, scoreUpdate }) { const question_answers = answers ? [...answers.results[0].incorrect_answers, answers.results[0].correct_answer] @@ -8,21 +9,28 @@ function Answers({ answers, isRightAnswer }) { const shuffled_answers = question_answers.sort(() => 0.5 - Math.random()); - function verifyAnswer(answer) { + function verifyAnswer(e, answer) { if (answer === answers.results[0].correct_answer) { console.log("Right!"); isRightAnswer(true); + scoreUpdate(score + 10); + e.target.classList.add('correct-answer'); } else { console.log("Wrong!"); isRightAnswer(false); + scoreUpdate(score - 10); + e.target.classList.add('disabled'); } } return (
{shuffled_answers.map(answer => { return })} diff --git a/src/components/App.js b/src/components/App.js index 2f4b6e1..1d3f921 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -1,5 +1,6 @@ import React from 'react'; import Header from './Header'; +import ScoreContainer from '../containers/ScoreContainer'; import QuestionContainer from '../containers/QuestionContainer'; import AnswersContainer from '../containers/AnswersContainer'; import MessageContainer from '../containers/MessageContainer'; @@ -12,6 +13,7 @@ class App extends React.Component { return (
+ diff --git a/src/components/Score.js b/src/components/Score.js new file mode 100644 index 0000000..624718e --- /dev/null +++ b/src/components/Score.js @@ -0,0 +1,9 @@ +import React from 'react'; + +function Score({ score }) { + return ( +
Points: {score}
+ ); +} + +export default Score; \ No newline at end of file diff --git a/src/containers/AnswersContainer.js b/src/containers/AnswersContainer.js index 75ac06e..8645a5a 100644 --- a/src/containers/AnswersContainer.js +++ b/src/containers/AnswersContainer.js @@ -1,15 +1,17 @@ import { connect } from 'react-redux' import Answers from '../components/Answers'; -import { isRightAnswer } from '../actions'; +import { isRightAnswer, scoreUpdate } from '../actions'; export const mapStateToProps = reduxStore => { return { - answers: reduxStore.quizQuestion + answers: reduxStore.quizQuestion, + score: reduxStore.score }; }; const mapDispatchToProps = dispatch => { return { + scoreUpdate: score => dispatch(scoreUpdate(score)), isRightAnswer: isRight => dispatch(isRightAnswer(isRight)) } }; diff --git a/src/containers/ScoreContainer.js b/src/containers/ScoreContainer.js new file mode 100644 index 0000000..b96214c --- /dev/null +++ b/src/containers/ScoreContainer.js @@ -0,0 +1,21 @@ +import { connect } from 'react-redux' +import Score from '../components/Score'; +// import { isRightAnswer } from '../actions'; + + +export const mapStateToProps = reduxStore => { + return { + score: reduxStore.score + }; +}; + +// const mapDispatchToProps = dispatch => { +// return { +// isRightAnswer: isRight => dispatch(isRightAnswer(isRight)) +// } +// }; + +export default connect( + mapStateToProps, + null +)(Score); \ No newline at end of file diff --git a/src/reducers/index.js b/src/reducers/index.js index 70e9953..bd27ce6 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -1,8 +1,10 @@ import { combineReducers } from 'redux'; import quizQuestion from './quizQuestion'; import quizAnswer from './quizAnswer'; +import score from './score'; export default combineReducers({ quizQuestion, - quizAnswer + quizAnswer, + score }); diff --git a/src/reducers/score.js b/src/reducers/score.js new file mode 100644 index 0000000..9aeb471 --- /dev/null +++ b/src/reducers/score.js @@ -0,0 +1,10 @@ +function score(state = 50, action) { + switch (action.type) { + case 'RECEIVE_SCORE': + return action.score + default: + return state + } +} + +export default score; \ No newline at end of file From 976020db5d3089d15ddd1fb9bd7364a07cfa6cb2 Mon Sep 17 00:00:00 2001 From: Ralph Date: Sun, 15 Jul 2018 12:00:20 +0100 Subject: [PATCH 09/24] Added fonts and colors --- src/actions/index.js | 50 ++++++++-------- src/components/Answers.js | 93 +++++++++++++++++++++++++++--- src/components/Header.js | 5 +- src/components/Message.js | 11 +++- src/components/Question.js | 6 +- src/components/Score.js | 7 ++- src/containers/AnswersContainer.js | 3 +- src/static/styles/_animations.scss | 68 ++++++++++++++++++++++ src/static/styles/_colors.scss | 6 ++ src/static/styles/_fonts.scss | 8 +++ src/static/styles/_global.scss | 4 ++ src/static/styles/answers.scss | 36 ++++++++++++ src/static/styles/header.scss | 15 ++++- src/static/styles/message.scss | 51 ++++++++++++++++ src/static/styles/question.scss | 19 ++++++ src/static/styles/score.scss | 5 ++ src/static/styles/style.scss | 6 +- 17 files changed, 350 insertions(+), 43 deletions(-) create mode 100644 src/static/styles/_animations.scss create mode 100644 src/static/styles/_colors.scss create mode 100644 src/static/styles/_fonts.scss create mode 100644 src/static/styles/_global.scss create mode 100644 src/static/styles/answers.scss create mode 100644 src/static/styles/message.scss create mode 100644 src/static/styles/question.scss create mode 100644 src/static/styles/score.scss diff --git a/src/actions/index.js b/src/actions/index.js index 42d8fea..41d8b3e 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -22,32 +22,32 @@ export function scoreUpdate(score) { export function fetchQuestion() { return function (dispatch) { - dispatch(receiveQuestion({ + // dispatch(receiveQuestion({ - "response_code": 0, - "results": [ - { - "category": "Entertainment: Television", - "type": "multiple", - "difficulty": "medium", - "question": "In Star Trek, what is the Ferengi's First Rule of Acquisition?", - "correct_answer": "Once you have their money, you never give it back. ", - "incorrect_answers": [ - "Never place friendship above profit", - "Greed is Eternal", - "Never allow family to stand in the way of opportunity" - ] - } - ] + // "response_code": 0, + // "results": [ + // { + // "category": "Entertainment: Television", + // "type": "multiple", + // "difficulty": "medium", + // "question": "In Star Trek, what is the Ferengi's First Rule of Acquisition?", + // "correct_answer": "Once you have their money, you never give it back. ", + // "incorrect_answers": [ + // "Never place friendship above profit", + // "Greed is Eternal", + // "Never allow family to stand in the way of opportunity" + // ] + // } + // ] - })); - // fetch(`https://opentdb.com/api.php?amount=1&type=multiple&encode=url3986`) - // .then(response => response.json()) - // .then(result => { - // dispatch(receiveQuestion(result)); - // }) - // .catch(function (error) { - // console.log(error); - // }); + // })); + fetch(`https://opentdb.com/api.php?amount=1&type=multiple&encode=url3986`) + .then(response => response.json()) + .then(result => { + dispatch(receiveQuestion(result)); + }) + .catch(function (error) { + console.log(error); + }); } } \ No newline at end of file diff --git a/src/components/Answers.js b/src/components/Answers.js index 7566f26..0ad9833 100644 --- a/src/components/Answers.js +++ b/src/components/Answers.js @@ -1,35 +1,48 @@ import React from 'react'; import cx from 'classnames'; +import '../static/styles/answers.scss'; -function Answers({ answers, isRightAnswer, score, scoreUpdate }) { +function Answers({ answers, isRightAnswer, score, scoreUpdate, requestQuestion }) { const question_answers = answers ? [...answers.results[0].incorrect_answers, answers.results[0].correct_answer] : []; - const shuffled_answers = question_answers.sort(() => 0.5 - Math.random()); + const shuffled_answers = question_answers; //.sort(() => 0.5 - Math.random()); function verifyAnswer(e, answer) { + e.preventDefault(); if (answer === answers.results[0].correct_answer) { - console.log("Right!"); + console.log("Correct!"); isRightAnswer(true); scoreUpdate(score + 10); - e.target.classList.add('correct-answer'); + e.target.classList.add('answers__button--correct-answer'); + e.target.classList.add('animated'); + e.target.classList.add('pulse'); + setTimeout(() => { + requestQuestion(); + isRightAnswer(false); + }, 2000) } else { console.log("Wrong!"); isRightAnswer(false); scoreUpdate(score - 10); - e.target.classList.add('disabled'); + e.target.classList.add('animated'); + e.target.classList.add('shake'); + e.target.classList.add('answers__button--wrong-answer'); } } + + return ( -
+
{shuffled_answers.map(answer => { return @@ -39,3 +52,67 @@ function Answers({ answers, isRightAnswer, score, scoreUpdate }) { } export default Answers; + + +// import React from 'react'; +// import cx from 'classnames'; +// import '../static/styles/answers.scss'; + +// class Answers extends React.Component { +// //({ answers, isRightAnswer, score, scoreUpdate }) +// constructor(props) { +// super(props); +// this.state = { +// question_answers: [] + +// // shuffled_answers: question_answers //.sort(() => 0.5 - Math.random()); +// } +// } + +// componentDidMount() { +// console.log("this.props.answers", this.props) +// this.setState( +// { +// question_answers: this.props.answers +// ? [...this.props.answers.results[0].incorrect_answers, this.props.answers.results[0].correct_answer] +// : ['sssss'], +// } +// ) +// } + +// verifyAnswer(e, answer) { +// e.preventDefault(); +// if (answer === this.props.answers.results[0].correct_answer) { +// console.log("Right!"); +// this.props.isRightAnswer(true); +// this.props.scoreUpdate(score + 10); +// e.target.classList.add('correct-answer'); +// } else { +// console.log("Wrong!"); +// this.props.isRightAnswer(false); +// this.props.scoreUpdate(score - 10); +// e.target.classList.add('disabled'); +// } +// } + +// render() { +// console.log("this.state.question_answers", this.state.question_answers) +// return ( +//
+// {this.state.question_answers.map(answer => { +// return +// })} +//
+// ) +// } +// } + +// export default Answers; diff --git a/src/components/Header.js b/src/components/Header.js index 2d1ab85..bb03c9f 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -3,8 +3,9 @@ import '../static/styles/header.scss'; function Header() { return ( -
-

QuizMachine

+
+

Quiz

+
Machine
); } diff --git a/src/components/Message.js b/src/components/Message.js index fb5822d..8110b52 100644 --- a/src/components/Message.js +++ b/src/components/Message.js @@ -1,8 +1,17 @@ import React from 'react'; +import '../static/styles/message.scss'; +import cx from 'classnames'; function Message({ questionAnswer }) { + const CSSClasses = cx('message ', { + visible: questionAnswer, + animated: questionAnswer, + fadeIn: questionAnswer, + }); return ( -
{questionAnswer ? "Right!" : ""}
+
+ {questionAnswer ? "Correct!" : ""} +
); } diff --git a/src/components/Question.js b/src/components/Question.js index a54683a..58035a8 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -1,4 +1,5 @@ import React from 'react'; +import "../static/styles/question.scss"; class Question extends React.Component { constructor(props) { @@ -12,11 +13,12 @@ class Question extends React.Component { render() { const { quizQuestion } = this.props; return ( -
+
{ quizQuestion ? quizQuestion.results.map(result => { - return

+ return

{decodeURIComponent(result.question)}

diff --git a/src/components/Score.js b/src/components/Score.js index 624718e..a64baaf 100644 --- a/src/components/Score.js +++ b/src/components/Score.js @@ -1,8 +1,13 @@ import React from 'react'; +import '../static/styles/score.scss'; function Score({ score }) { return ( -
Points: {score}
+
+ + Points: {score} + +
); } diff --git a/src/containers/AnswersContainer.js b/src/containers/AnswersContainer.js index 8645a5a..3d3ff0a 100644 --- a/src/containers/AnswersContainer.js +++ b/src/containers/AnswersContainer.js @@ -1,6 +1,6 @@ import { connect } from 'react-redux' import Answers from '../components/Answers'; -import { isRightAnswer, scoreUpdate } from '../actions'; +import { isRightAnswer, scoreUpdate, fetchQuestion } from '../actions'; export const mapStateToProps = reduxStore => { return { @@ -11,6 +11,7 @@ export const mapStateToProps = reduxStore => { const mapDispatchToProps = dispatch => { return { + requestQuestion: () => dispatch(fetchQuestion()), scoreUpdate: score => dispatch(scoreUpdate(score)), isRightAnswer: isRight => dispatch(isRightAnswer(isRight)) } diff --git a/src/static/styles/_animations.scss b/src/static/styles/_animations.scss new file mode 100644 index 0000000..96267b2 --- /dev/null +++ b/src/static/styles/_animations.scss @@ -0,0 +1,68 @@ +/* originally authored by Dan Eden - https://github.com/daneden/animate.css */ + +.animated { + animation-duration: 1s; + animation-fill-mode: both; + } + + .animated.infinite { + animation-iteration-count: infinite; + } + + @keyframes fadeIn { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + +.fadeIn { + animation-name: fadeIn; +} + + @keyframes pulse { + from { + transform: scale3d(1, 1, 1); + } + + 50% { + transform: scale3d(1.05, 1.05, 1.05); + } + + to { + transform: scale3d(1, 1, 1); + } + } + + .pulse { + animation-name: pulse; + } + +@keyframes shake { + from, + to { + transform: translate3d(0, 0, 0); + } + + 10%, + 30%, + 50%, + 70%, + 90% { + transform: translate3d(-3px, 0, 0); + } + + 20%, + 40%, + 60%, + 80% { + transform: translate3d(3px, 0, 0); + } + } + + .shake { + animation-name: shake; + } \ No newline at end of file diff --git a/src/static/styles/_colors.scss b/src/static/styles/_colors.scss new file mode 100644 index 0000000..2417bbf --- /dev/null +++ b/src/static/styles/_colors.scss @@ -0,0 +1,6 @@ +:root { + --primary-color: #27CC92; + --secondary-color: #18986B; + --correct-answer-color: green; + --wrong-answer-color: tomato; +} \ No newline at end of file diff --git a/src/static/styles/_fonts.scss b/src/static/styles/_fonts.scss new file mode 100644 index 0000000..b3d5ca5 --- /dev/null +++ b/src/static/styles/_fonts.scss @@ -0,0 +1,8 @@ +@import url('https://fonts.googleapis.com/css?family=Bitter'); +// font-family: 'Bitter', serif; + +@import url('https://fonts.googleapis.com/css?family=Open+Sans'); +//font-family: 'Open Sans', sans-serif; + +@import url('https://fonts.googleapis.com/css?family=Dancing+Script'); +//font-family: 'Dancing Script', cursive; \ No newline at end of file diff --git a/src/static/styles/_global.scss b/src/static/styles/_global.scss new file mode 100644 index 0000000..e3a079d --- /dev/null +++ b/src/static/styles/_global.scss @@ -0,0 +1,4 @@ +body { + background-color: var(--primary-color); + font-family: 'Open Sans', sans-serif; +} \ No newline at end of file diff --git a/src/static/styles/answers.scss b/src/static/styles/answers.scss new file mode 100644 index 0000000..e598626 --- /dev/null +++ b/src/static/styles/answers.scss @@ -0,0 +1,36 @@ +.answers { + display: grid; + grid-template-columns: 100%; + grid-gap: 10px; + width: 800px; + max-width: 100%; + margin-left: auto; + margin-right: auto; + + .answers__button { + padding: 10px 20px; + font-size: 0.9rem; + border: none; + background-color: #fff; + color: var(--background-color); + + &:hover { + cursor: pointer; + opacity: .8; + } + + &.answers__button--correct-answer { + background-color:var(--correct-answer-color); + color: #fff; + } + + &.answers__button--wrong-answer { + background-color:var(--wrong-answer-color); + color: #fff; + } + } + + @media(min-width: 768px){ + grid-template-columns: 50% 50%; + } +} \ No newline at end of file diff --git a/src/static/styles/header.scss b/src/static/styles/header.scss index acbbda4..75277e4 100644 --- a/src/static/styles/header.scss +++ b/src/static/styles/header.scss @@ -1,3 +1,14 @@ -h1 { - color: pink; +.main-header__logo { + font-size: 7rem; + text-align: center; + color: #fff; + font-family: 'Dancing Script', cursive; + margin: 0; +} +.main-header__subtext { + font-size: 1.8rem; + text-align: center; + color: #fff; + font-family: 'Dancing Script', cursive; + margin: -20px 0 30px 10px; } \ No newline at end of file diff --git a/src/static/styles/message.scss b/src/static/styles/message.scss new file mode 100644 index 0000000..358e4ea --- /dev/null +++ b/src/static/styles/message.scss @@ -0,0 +1,51 @@ +.message { + position: absolute; + top: 50%; + left: 50%; + color: #fff; + font-size: 36px; + transform: rotate(-4deg) translate(-50%, -60%); + font-family: 'Bitter', serif; + + background-color: #fcaa02; + width: 150px; + height: 150px; + border-radius: 10px; + z-index: 9999; + display: none; + + // &.visible { + // display: block; + // } + + &:after { + content: ""; + background-color: #fcaa02; + width: 150px; + height: 150px; + border-radius: 10px; + transform: rotate(30deg); + position: absolute; + top: 0; + left: 0; + } + + &:before { + content: ""; + background-color: #fcaa02; + width: 150px; + height: 150px; + border-radius: 10px; + transform: rotate(60deg); + position: absolute; + top: 0; + left: 0; + } + + .message__text { + z-index: 99999; + position: absolute; + top: 33%; + left: 6%; + } +} \ No newline at end of file diff --git a/src/static/styles/question.scss b/src/static/styles/question.scss new file mode 100644 index 0000000..2a6cbc8 --- /dev/null +++ b/src/static/styles/question.scss @@ -0,0 +1,19 @@ +.question { + .question__text { + text-align: center; + font-size: 1.8rem; + color: var(--secondary-color); + position: relative; + font-family: 'Bitter', serif; + + &::before { + content: "Q"; + position: absolute; + font-size: 6rem; + top: -30px; + left: -6px; + opacity: 0.3; + + } + } +} \ No newline at end of file diff --git a/src/static/styles/score.scss b/src/static/styles/score.scss new file mode 100644 index 0000000..a32eb62 --- /dev/null +++ b/src/static/styles/score.scss @@ -0,0 +1,5 @@ +.score { + background-color: #dff0d8; + padding: 2px 5px; + color: var(--secondary-color); +} \ No newline at end of file diff --git a/src/static/styles/style.scss b/src/static/styles/style.scss index 66d329a..f097e2f 100644 --- a/src/static/styles/style.scss +++ b/src/static/styles/style.scss @@ -1 +1,5 @@ -@import './layout' \ No newline at end of file +@import './_fonts'; +@import './_colors'; +@import './_layout'; +@import './_global'; +@import './_animations'; \ No newline at end of file From 9a2e061f461490971cf3da0c87ec9c36fae85f54 Mon Sep 17 00:00:00 2001 From: Ralph Date: Sun, 15 Jul 2018 12:40:02 +0100 Subject: [PATCH 10/24] Replace Next button with Skip question button --- src/components/App.js | 4 ++-- src/components/ButtonNext.js | 11 ---------- src/components/ButtonSkipQuestion.js | 16 ++++++++++++++ src/containers/ButtonNextContainer.js | 15 ------------- src/containers/ButtonSkipQuestionContainer.js | 22 +++++++++++++++++++ src/static/styles/buttonSkipQuestion.scss | 17 ++++++++++++++ 6 files changed, 57 insertions(+), 28 deletions(-) delete mode 100644 src/components/ButtonNext.js create mode 100644 src/components/ButtonSkipQuestion.js delete mode 100644 src/containers/ButtonNextContainer.js create mode 100644 src/containers/ButtonSkipQuestionContainer.js create mode 100644 src/static/styles/buttonSkipQuestion.scss diff --git a/src/components/App.js b/src/components/App.js index 1d3f921..93e547f 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -4,7 +4,7 @@ import ScoreContainer from '../containers/ScoreContainer'; import QuestionContainer from '../containers/QuestionContainer'; import AnswersContainer from '../containers/AnswersContainer'; import MessageContainer from '../containers/MessageContainer'; -import ButtonNextContainer from '../containers/ButtonNextContainer'; +import ButtonSkipQuestionContainer from '../containers/ButtonSkipQuestionContainer'; import '../static/styles/style.scss'; @@ -17,7 +17,7 @@ class App extends React.Component { - +
) } diff --git a/src/components/ButtonNext.js b/src/components/ButtonNext.js deleted file mode 100644 index eafbf40..0000000 --- a/src/components/ButtonNext.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react'; -function ButtonNext({ requestQuestion, isRightAnswer }) { - return ( - - ); -} - -export default ButtonNext; \ No newline at end of file diff --git a/src/components/ButtonSkipQuestion.js b/src/components/ButtonSkipQuestion.js new file mode 100644 index 0000000..6d21c5d --- /dev/null +++ b/src/components/ButtonSkipQuestion.js @@ -0,0 +1,16 @@ +import React from 'react'; +import "../static/styles/buttonSkipQuestion.scss"; + +function ButtonSkipQuestion({ requestQuestion, isRightAnswer, scoreUpdate, score }) { + return ( +
+ +
+ ); +} + +export default ButtonSkipQuestion; \ No newline at end of file diff --git a/src/containers/ButtonNextContainer.js b/src/containers/ButtonNextContainer.js deleted file mode 100644 index 0c667f9..0000000 --- a/src/containers/ButtonNextContainer.js +++ /dev/null @@ -1,15 +0,0 @@ -import { connect } from 'react-redux' -import ButtonNext from '../components/ButtonNext'; -import { fetchQuestion, isRightAnswer } from '../actions'; - -const mapDispatchToProps = dispatch => { - return { - isRightAnswer: isRight => dispatch(isRightAnswer(isRight)), - requestQuestion: () => dispatch(fetchQuestion()) - } -}; - -export default connect( - null, - mapDispatchToProps -)(ButtonNext); \ No newline at end of file diff --git a/src/containers/ButtonSkipQuestionContainer.js b/src/containers/ButtonSkipQuestionContainer.js new file mode 100644 index 0000000..70657b3 --- /dev/null +++ b/src/containers/ButtonSkipQuestionContainer.js @@ -0,0 +1,22 @@ +import { connect } from 'react-redux' +import ButtonSkipQuestion from '../components/ButtonSkipQuestion'; +import { fetchQuestion, isRightAnswer, scoreUpdate } from '../actions'; + +export const mapStateToProps = reduxStore => { + return { + score: reduxStore.score + }; +}; + +const mapDispatchToProps = dispatch => { + return { + scoreUpdate: score => dispatch(scoreUpdate(score)), + isRightAnswer: isRight => dispatch(isRightAnswer(isRight)), + requestQuestion: () => dispatch(fetchQuestion()) + } +}; + +export default connect( + mapStateToProps, + mapDispatchToProps +)(ButtonSkipQuestion); \ No newline at end of file diff --git a/src/static/styles/buttonSkipQuestion.scss b/src/static/styles/buttonSkipQuestion.scss new file mode 100644 index 0000000..8db6243 --- /dev/null +++ b/src/static/styles/buttonSkipQuestion.scss @@ -0,0 +1,17 @@ +.skip-question { + display: flex; + justify-content: flex-end; + + .skip-question-button { + padding: 10px 20px; + background-color: #cf8c00; + border: none; + color: #fff; + margin-top: 20px; + + &:hover { + cursor: pointer; + opacity: .8; + } + } +} \ No newline at end of file From f085f3356c87a76828500fe88551bd4e06299530 Mon Sep 17 00:00:00 2001 From: Ralph Date: Sun, 15 Jul 2018 13:12:21 +0100 Subject: [PATCH 11/24] Added disabled attribute to clicked buttons --- src/components/Answers.js | 1 + src/static/styles/answers.scss | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/Answers.js b/src/components/Answers.js index 0ad9833..941972d 100644 --- a/src/components/Answers.js +++ b/src/components/Answers.js @@ -30,6 +30,7 @@ function Answers({ answers, isRightAnswer, score, scoreUpdate, requestQuestion } e.target.classList.add('animated'); e.target.classList.add('shake'); e.target.classList.add('answers__button--wrong-answer'); + e.target.setAttribute("disabled", "disabled"); } } diff --git a/src/static/styles/answers.scss b/src/static/styles/answers.scss index e598626..9e8719c 100644 --- a/src/static/styles/answers.scss +++ b/src/static/styles/answers.scss @@ -14,7 +14,7 @@ background-color: #fff; color: var(--background-color); - &:hover { + &:not([disabled]):hover { cursor: pointer; opacity: .8; } From b4726237e89cccb8ceacce93e106c35ad2ec00f4 Mon Sep 17 00:00:00 2001 From: Ralph Date: Sun, 15 Jul 2018 20:12:06 +0100 Subject: [PATCH 12/24] Added category and difficulty info to score panel --- src/actions/index.js | 62 ++++++---- src/components/Answers.js | 19 ++- src/components/App.js | 2 + src/components/ButtonSkipQuestion.js | 4 +- src/components/Options.js | 112 ++++++++++++++++++ src/components/Score.js | 6 +- src/containers/AnswersContainer.js | 6 +- src/containers/ButtonSkipQuestionContainer.js | 12 +- src/containers/OptionsContainer.js | 23 ++++ src/containers/ScoreContainer.js | 4 +- src/reducers/index.js | 8 +- src/reducers/optionsCategory.js | 11 ++ src/reducers/optionsCategoryName.js | 11 ++ src/reducers/optionsDifficulty.js | 11 ++ src/reducers/score.js | 4 +- src/static/styles/_colors.scss | 1 + src/static/styles/buttonSkipQuestion.scss | 2 +- src/static/styles/options.scss | 83 +++++++++++++ src/static/styles/score.scss | 15 +++ 19 files changed, 351 insertions(+), 45 deletions(-) create mode 100644 src/components/Options.js create mode 100644 src/containers/OptionsContainer.js create mode 100644 src/reducers/optionsCategory.js create mode 100644 src/reducers/optionsCategoryName.js create mode 100644 src/reducers/optionsDifficulty.js create mode 100644 src/static/styles/options.scss diff --git a/src/actions/index.js b/src/actions/index.js index 41d8b3e..25c2301 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -20,28 +20,30 @@ export function scoreUpdate(score) { } } -export function fetchQuestion() { +export function optionsCategory(optionsCategory) { + return { + type: 'RECEIVE_OPTIONS_CATEGORY', + optionsCategory + } +} + +export function optionsCategoryName(optionsCategoryName) { + return { + type: 'RECEIVE_OPTIONS_CATEGORY_NAME', + optionsCategoryName + } +} + +export function optionsDifficulty(optionsDifficulty) { + return { + type: 'RECEIVE_OPTIONS_DIFFICULTY', + optionsDifficulty + } +} + +export function fetchQuestion(category = '', difficulty = '') { return function (dispatch) { - // dispatch(receiveQuestion({ - - // "response_code": 0, - // "results": [ - // { - // "category": "Entertainment: Television", - // "type": "multiple", - // "difficulty": "medium", - // "question": "In Star Trek, what is the Ferengi's First Rule of Acquisition?", - // "correct_answer": "Once you have their money, you never give it back. ", - // "incorrect_answers": [ - // "Never place friendship above profit", - // "Greed is Eternal", - // "Never allow family to stand in the way of opportunity" - // ] - // } - // ] - - // })); - fetch(`https://opentdb.com/api.php?amount=1&type=multiple&encode=url3986`) + fetch(`https://opentdb.com/api.php?amount=1&type=multiple&category=${category}&difficulty=${difficulty}&encode=url3986`) .then(response => response.json()) .then(result => { dispatch(receiveQuestion(result)); @@ -50,4 +52,22 @@ export function fetchQuestion() { console.log(error); }); } + // dispatch(receiveQuestion({ + // "response_code": 0, + // "results": [ + // { + // "category": "Entertainment: Television", + // "type": "multiple", + // "difficulty": "medium", + // "question": "In Star Trek, what is the Ferengi's First Rule of Acquisition?", + // "correct_answer": "Once you have their money, you never give it back. ", + // "incorrect_answers": [ + // "Never place friendship above profit", + // "Greed is Eternal", + // "Never allow family to stand in the way of opportunity" + // ] + // } + // ] + + // })); } \ No newline at end of file diff --git a/src/components/Answers.js b/src/components/Answers.js index 941972d..4c665e4 100644 --- a/src/components/Answers.js +++ b/src/components/Answers.js @@ -2,7 +2,7 @@ import React from 'react'; import cx from 'classnames'; import '../static/styles/answers.scss'; -function Answers({ answers, isRightAnswer, score, scoreUpdate, requestQuestion }) { +function Answers({ answers, isRightAnswer, score, scoreUpdate, requestQuestion, category, difficulty }) { const question_answers = answers ? [...answers.results[0].incorrect_answers, answers.results[0].correct_answer] @@ -13,23 +13,17 @@ function Answers({ answers, isRightAnswer, score, scoreUpdate, requestQuestion } function verifyAnswer(e, answer) { e.preventDefault(); if (answer === answers.results[0].correct_answer) { - console.log("Correct!"); isRightAnswer(true); scoreUpdate(score + 10); - e.target.classList.add('answers__button--correct-answer'); - e.target.classList.add('animated'); - e.target.classList.add('pulse'); + e.target.classList.add('animated', 'pulse', 'answers__button--correct-answer'); setTimeout(() => { - requestQuestion(); + requestQuestion(category, difficulty); isRightAnswer(false); }, 2000) } else { - console.log("Wrong!"); isRightAnswer(false); scoreUpdate(score - 10); - e.target.classList.add('animated'); - e.target.classList.add('shake'); - e.target.classList.add('answers__button--wrong-answer'); + e.target.classList.add('animated', 'shake', 'answers__button--wrong-answer'); e.target.setAttribute("disabled", "disabled"); } } @@ -40,7 +34,10 @@ function Answers({ answers, isRightAnswer, score, scoreUpdate, requestQuestion } {shuffled_answers.map(answer => { return
diff --git a/src/components/Options.js b/src/components/Options.js new file mode 100644 index 0000000..bfcc712 --- /dev/null +++ b/src/components/Options.js @@ -0,0 +1,112 @@ +import React from 'react'; +import cx from 'classnames'; +import "../static/styles/options.scss"; + +class Options extends React.Component { + constructor(props) { + super(props); + this.state = { + category: '', + categoryName: '', + difficulty: '', + optionsOpen: false + } + + this.updateCategory = this.updateCategory.bind(this); + this.updateDifficulty = this.updateDifficulty.bind(this); + this.toggleOptions = this.toggleOptions.bind(this); + this.updateCategory = this.updateCategory.bind(this); + this.updateDifficulty = this.updateDifficulty.bind(this); + } + + updateCategory(e) { + this.setState({ + category: e.target.value, + categoryName: e.target.selectedOptions[0].text // get text of the option tag not the value + }); + } + + updateDifficulty(e) { + this.setState({ + difficulty: e.target.value + }); + } + + updateReduxCategory() { + this.props.optionsCategory(this.state.category); + this.props.optionsCategoryName(this.state.categoryName); + } + + updateReduxDifficulty() { + this.props.optionsDifficulty(this.state.difficulty); + } + + toggleOptions() { + this.setState({ + optionsOpen: !this.state.optionsOpen + }) + } + + render() { + const CSSClasses = cx('options__list ', { + visible: this.state.optionsOpen + }); + return ( +
+
+ +
+
+
+ +
+
+ +
+ +
+
+ ); + }; +} +export default Options; diff --git a/src/components/Score.js b/src/components/Score.js index a64baaf..54b9470 100644 --- a/src/components/Score.js +++ b/src/components/Score.js @@ -1,9 +1,13 @@ import React from 'react'; import '../static/styles/score.scss'; -function Score({ score }) { +function Score({ score, categoryName, difficulty }) { return (
+
+ Category: {categoryName !== "" ? categoryName : "All"} + Difficulty: {difficulty !== "" ? difficulty : "Easy"} +
Points: {score} diff --git a/src/containers/AnswersContainer.js b/src/containers/AnswersContainer.js index 3d3ff0a..f6d3e38 100644 --- a/src/containers/AnswersContainer.js +++ b/src/containers/AnswersContainer.js @@ -5,13 +5,15 @@ import { isRightAnswer, scoreUpdate, fetchQuestion } from '../actions'; export const mapStateToProps = reduxStore => { return { answers: reduxStore.quizQuestion, - score: reduxStore.score + score: reduxStore.score, + category: reduxStore.optionsCategory, + difficulty: reduxStore.optionsDifficulty }; }; const mapDispatchToProps = dispatch => { return { - requestQuestion: () => dispatch(fetchQuestion()), + requestQuestion: (category, difficulty) => dispatch(fetchQuestion(category, difficulty)), scoreUpdate: score => dispatch(scoreUpdate(score)), isRightAnswer: isRight => dispatch(isRightAnswer(isRight)) } diff --git a/src/containers/ButtonSkipQuestionContainer.js b/src/containers/ButtonSkipQuestionContainer.js index 70657b3..392366e 100644 --- a/src/containers/ButtonSkipQuestionContainer.js +++ b/src/containers/ButtonSkipQuestionContainer.js @@ -1,10 +1,16 @@ import { connect } from 'react-redux' import ButtonSkipQuestion from '../components/ButtonSkipQuestion'; -import { fetchQuestion, isRightAnswer, scoreUpdate } from '../actions'; +import { + fetchQuestion, + isRightAnswer, + scoreUpdate +} from '../actions'; export const mapStateToProps = reduxStore => { return { - score: reduxStore.score + score: reduxStore.score, + category: reduxStore.optionsCategory, + difficulty: reduxStore.optionsDifficulty }; }; @@ -12,7 +18,7 @@ const mapDispatchToProps = dispatch => { return { scoreUpdate: score => dispatch(scoreUpdate(score)), isRightAnswer: isRight => dispatch(isRightAnswer(isRight)), - requestQuestion: () => dispatch(fetchQuestion()) + requestQuestion: (category, difficulty) => dispatch(fetchQuestion(category, difficulty)) } }; diff --git a/src/containers/OptionsContainer.js b/src/containers/OptionsContainer.js new file mode 100644 index 0000000..bc9b29a --- /dev/null +++ b/src/containers/OptionsContainer.js @@ -0,0 +1,23 @@ +import { connect } from 'react-redux' +import Options from '../components/Options'; +import { fetchQuestion, optionsDifficulty, optionsCategory, optionsCategoryName } from '../actions'; + +// export const mapStateToProps = reduxStore => { +// return { +// quizQuestion: reduxStore.quizQuestion +// }; +// }; + +const mapDispatchToProps = dispatch => { + return { + requestQuestionsUpdate: (category, difficulty) => dispatch(fetchQuestion(category, difficulty)), + optionsDifficulty: difficulty => dispatch(optionsDifficulty(difficulty)), + optionsCategory: category => dispatch(optionsCategory(category)), + optionsCategoryName: categoryName => dispatch(optionsCategoryName(categoryName)) + } +}; + +export default connect( + null, + mapDispatchToProps +)(Options); \ No newline at end of file diff --git a/src/containers/ScoreContainer.js b/src/containers/ScoreContainer.js index b96214c..ad72b72 100644 --- a/src/containers/ScoreContainer.js +++ b/src/containers/ScoreContainer.js @@ -5,7 +5,9 @@ import Score from '../components/Score'; export const mapStateToProps = reduxStore => { return { - score: reduxStore.score + score: reduxStore.score, + categoryName: reduxStore.optionsCategoryName, + difficulty: reduxStore.optionsDifficulty }; }; diff --git a/src/reducers/index.js b/src/reducers/index.js index bd27ce6..756eed7 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -2,9 +2,15 @@ import { combineReducers } from 'redux'; import quizQuestion from './quizQuestion'; import quizAnswer from './quizAnswer'; import score from './score'; +import optionsDifficulty from './optionsDifficulty'; +import optionsCategory from './optionsCategory'; +import optionsCategoryName from './optionsCategoryName'; export default combineReducers({ quizQuestion, quizAnswer, - score + score, + optionsDifficulty, + optionsCategory, + optionsCategoryName }); diff --git a/src/reducers/optionsCategory.js b/src/reducers/optionsCategory.js new file mode 100644 index 0000000..c677279 --- /dev/null +++ b/src/reducers/optionsCategory.js @@ -0,0 +1,11 @@ +function optionsCategory( + state = '', action) { + switch (action.type) { + case 'RECEIVE_OPTIONS_CATEGORY': + return action.optionsCategory + default: + return state + } +} + +export default optionsCategory; \ No newline at end of file diff --git a/src/reducers/optionsCategoryName.js b/src/reducers/optionsCategoryName.js new file mode 100644 index 0000000..415de22 --- /dev/null +++ b/src/reducers/optionsCategoryName.js @@ -0,0 +1,11 @@ +function optionsCategoryName( + state = '', action) { + switch (action.type) { + case 'RECEIVE_OPTIONS_CATEGORY_NAME': + return action.optionsCategoryName + default: + return state + } +} + +export default optionsCategoryName; \ No newline at end of file diff --git a/src/reducers/optionsDifficulty.js b/src/reducers/optionsDifficulty.js new file mode 100644 index 0000000..3faa36c --- /dev/null +++ b/src/reducers/optionsDifficulty.js @@ -0,0 +1,11 @@ +function optionsDifficulty( + state = '', action) { + switch (action.type) { + case 'RECEIVE_OPTIONS_DIFFICULTY': + return action.optionsDifficulty + default: + return state + } +} + +export default optionsDifficulty; \ No newline at end of file diff --git a/src/reducers/score.js b/src/reducers/score.js index 9aeb471..f6c56dd 100644 --- a/src/reducers/score.js +++ b/src/reducers/score.js @@ -1,9 +1,9 @@ -function score(state = 50, action) { +function score(score = 50, action) { switch (action.type) { case 'RECEIVE_SCORE': return action.score default: - return state + return score } } diff --git a/src/static/styles/_colors.scss b/src/static/styles/_colors.scss index 2417bbf..8c69b9e 100644 --- a/src/static/styles/_colors.scss +++ b/src/static/styles/_colors.scss @@ -1,6 +1,7 @@ :root { --primary-color: #27CC92; --secondary-color: #18986B; + --tertiary-color: #cf8c00; --correct-answer-color: green; --wrong-answer-color: tomato; } \ No newline at end of file diff --git a/src/static/styles/buttonSkipQuestion.scss b/src/static/styles/buttonSkipQuestion.scss index 8db6243..9661e02 100644 --- a/src/static/styles/buttonSkipQuestion.scss +++ b/src/static/styles/buttonSkipQuestion.scss @@ -4,7 +4,7 @@ .skip-question-button { padding: 10px 20px; - background-color: #cf8c00; + background-color: var(--tertiary-color); border: none; color: #fff; margin-top: 20px; diff --git a/src/static/styles/options.scss b/src/static/styles/options.scss new file mode 100644 index 0000000..2218e1d --- /dev/null +++ b/src/static/styles/options.scss @@ -0,0 +1,83 @@ +.options { + .options__list { + display: none; + + &.visible { + display: block; + } + } + + .options__toggle { + display: flex; + justify-content: flex-end; + + .options__toggle__button { + background: none; + border: none; + font-size: 0.9rem; + padding: 0; + margin-bottom: 10px; + color: #fff; + + &:hover { + cursor: pointer; + opacity: .8; + } + } + } + + .options__button-update { + padding: 10px 20px; + background-color: var(--tertiary-color); + border: none; + color: #fff; + margin-bottom: 20px; + width: 100%; + + &:hover { + cursor: pointer; + opacity: .8; + } + } +} + +.custom-select { + background-color: var(--secondary-color); + border: 0; + overflow: hidden; + width: 100%; + height: 35px; + position: relative; + margin-bottom: 10px; + + &:after { + content: "â–¾"; + position: absolute; + right: 10px; + top: 5px; + color: var(--primary-color); + } + + select { + padding: 8px; + width: 100%; + border: none; + box-shadow: none; + background: transparent; + background-image: none; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + color: #fff; + font-size: 0.8rem; + + &:focus { + border: 0; + box-shadow: none !important; + } + + option { + width: 100%; + } + } +} \ No newline at end of file diff --git a/src/static/styles/score.scss b/src/static/styles/score.scss index a32eb62..e701778 100644 --- a/src/static/styles/score.scss +++ b/src/static/styles/score.scss @@ -1,5 +1,20 @@ .score { + display: flex; + justify-content: space-between; + background-color: #dff0d8; padding: 2px 5px; color: var(--secondary-color); + + .score__text { + display: flex; + align-items: center; + justify-content: center; + } + + .category { + display: flex; + flex-direction: column; + font-size: 0.9rem; + } } \ No newline at end of file From 65ebdb718368fdb818473bd4c5a29325154bd2d8 Mon Sep 17 00:00:00 2001 From: Ralph Date: Sun, 15 Jul 2018 23:30:58 +0100 Subject: [PATCH 13/24] Added questions limit --- src/actions/index.js | 18 +++++- src/components/Answers.js | 33 ++++++++-- src/components/ButtonSkipQuestion.js | 24 ++++++- src/components/Options.js | 64 +++++++++++++++++-- src/components/Question.js | 13 ++-- src/components/Score.js | 6 +- src/containers/AnswersContainer.js | 9 ++- src/containers/ButtonSkipQuestionContainer.js | 10 ++- src/containers/OptionsContainer.js | 25 +++++--- src/containers/QuestionContainer.js | 3 +- src/containers/ScoreContainer.js | 4 +- src/reducers/currentQuestion.js | 11 ++++ src/reducers/index.js | 6 +- src/reducers/updateReduxQuestionsAmount.js | 11 ++++ src/static/styles/buttonSkipQuestion.scss | 4 ++ src/static/styles/score.scss | 4 +- 16 files changed, 203 insertions(+), 42 deletions(-) create mode 100644 src/reducers/currentQuestion.js create mode 100644 src/reducers/updateReduxQuestionsAmount.js diff --git a/src/actions/index.js b/src/actions/index.js index 25c2301..700fb6e 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -41,9 +41,23 @@ export function optionsDifficulty(optionsDifficulty) { } } -export function fetchQuestion(category = '', difficulty = '') { +export function currentQuestion(currentQuestion) { + return { + type: 'RECEIVE_CURRENT_QUESTION', + currentQuestion + } +} + +export function updateReduxQuestionsAmount(questionsAmount) { + return { + type: 'RECEIVE_QUESTION_AMOUNT', + updateReduxQuestionsAmount: questionsAmount + } +} + +export function fetchQuestion(category = '', difficulty = '', amount = 1) { return function (dispatch) { - fetch(`https://opentdb.com/api.php?amount=1&type=multiple&category=${category}&difficulty=${difficulty}&encode=url3986`) + fetch(`https://opentdb.com/api.php?amount=${amount}&type=multiple&category=${category}&difficulty=${difficulty}&encode=url3986`) .then(response => response.json()) .then(result => { dispatch(receiveQuestion(result)); diff --git a/src/components/Answers.js b/src/components/Answers.js index 4c665e4..d98aa8b 100644 --- a/src/components/Answers.js +++ b/src/components/Answers.js @@ -2,7 +2,18 @@ import React from 'react'; import cx from 'classnames'; import '../static/styles/answers.scss'; -function Answers({ answers, isRightAnswer, score, scoreUpdate, requestQuestion, category, difficulty }) { +function Answers({ + answers, + isRightAnswer, + score, + scoreUpdate, + requestQuestion, + category, + difficulty, + incrementCurrentQuestion, + currentQuestion, + totalQuestions +}) { const question_answers = answers ? [...answers.results[0].incorrect_answers, answers.results[0].correct_answer] @@ -12,12 +23,12 @@ function Answers({ answers, isRightAnswer, score, scoreUpdate, requestQuestion, function verifyAnswer(e, answer) { e.preventDefault(); + if (currentQuestion === +totalQuestions) return; if (answer === answers.results[0].correct_answer) { isRightAnswer(true); scoreUpdate(score + 10); e.target.classList.add('animated', 'pulse', 'answers__button--correct-answer'); setTimeout(() => { - requestQuestion(category, difficulty); isRightAnswer(false); }, 2000) } else { @@ -28,6 +39,20 @@ function Answers({ answers, isRightAnswer, score, scoreUpdate, requestQuestion, } } + function endOfQuestions() { + // console.log("currentQuestion", currentQuestion); + // console.log("totalQuestions", totalQuestions); + if (currentQuestion === +totalQuestions) { + // Open end game message + console.log('game ends'); + } else { + setTimeout(() => { + requestQuestion(category, difficulty); + isRightAnswer(false); + }, 2000) + incrementCurrentQuestion(currentQuestion + 1); + } + } return (
@@ -36,7 +61,7 @@ function Answers({ answers, isRightAnswer, score, scoreUpdate, requestQuestion, type="button" onClick={(e) => { verifyAnswer(e, answer); - requestQuestions(category, difficulty); + endOfQuestions(); }} key={answer} className={cx('answers__button', { @@ -45,7 +70,7 @@ function Answers({ answers, isRightAnswer, score, scoreUpdate, requestQuestion, {decodeURIComponent(answer)} })} -
+
) } diff --git a/src/components/ButtonSkipQuestion.js b/src/components/ButtonSkipQuestion.js index b6f22c0..cf79192 100644 --- a/src/components/ButtonSkipQuestion.js +++ b/src/components/ButtonSkipQuestion.js @@ -1,12 +1,30 @@ import React from 'react'; +import cx from 'classnames'; import "../static/styles/buttonSkipQuestion.scss"; -function ButtonSkipQuestion({ requestQuestion, isRightAnswer, scoreUpdate, score, category, difficulty }) { +function ButtonSkipQuestion({ + requestQuestion, + isRightAnswer, + scoreUpdate, + score, + category, + difficulty, + currentQuestion, + incrementCurrentQuestion, + totalQuestions +}) { return ( -
+
diff --git a/src/components/Options.js b/src/components/Options.js index bfcc712..6f14ad7 100644 --- a/src/components/Options.js +++ b/src/components/Options.js @@ -9,20 +9,26 @@ class Options extends React.Component { category: '', categoryName: '', difficulty: '', - optionsOpen: false + optionsOpen: false, + questionsAmount: 10 } this.updateCategory = this.updateCategory.bind(this); this.updateDifficulty = this.updateDifficulty.bind(this); this.toggleOptions = this.toggleOptions.bind(this); this.updateCategory = this.updateCategory.bind(this); + // this.updateReduxCategory = this.updateCategory.bind(this); this.updateDifficulty = this.updateDifficulty.bind(this); + // this.updateReduxDifficulty = this.updateDifficulty.bind(this); + this.updateQuestionsAmount = this.updateQuestionsAmount.bind(this); + // this.updateReduxQuestionsAmount = this.updateReduxQuestionsAmount.bind(this); } updateCategory(e) { this.setState({ category: e.target.value, - categoryName: e.target.selectedOptions[0].text // get text of the option tag not the value + categoryName: e.target.selectedOptions ? e.target.selectedOptions[0].text : "All", // get text of the option tag not the value + // questionsAmount: }); } @@ -32,6 +38,12 @@ class Options extends React.Component { }); } + updateQuestionsAmount(e) { + this.setState({ + questionsAmount: e.target.value + }); + } + updateReduxCategory() { this.props.optionsCategory(this.state.category); this.props.optionsCategoryName(this.state.categoryName); @@ -41,6 +53,11 @@ class Options extends React.Component { this.props.optionsDifficulty(this.state.difficulty); } + updateReduxQuestionsAmount() { + // console.log("this.state.questionsAmount", this.state.questionsAmount) + this.props.updateReduxQuestionsAmount(this.state.questionsAmount); + } + toggleOptions() { this.setState({ optionsOpen: !this.state.optionsOpen @@ -94,18 +111,57 @@ class Options extends React.Component {
+
+ +
-
+
); }; } diff --git a/src/components/Question.js b/src/components/Question.js index 58035a8..3ec08be 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -11,18 +11,15 @@ class Question extends React.Component { } render() { - const { quizQuestion } = this.props; + const { quizQuestion, currentQuestion } = this.props; return (
{ quizQuestion - ? quizQuestion.results.map(result => { - return

- {decodeURIComponent(result.question)} -

- - }) + ?

+ {decodeURIComponent(quizQuestion.results[0].question)} +

: "" } diff --git a/src/components/Score.js b/src/components/Score.js index 54b9470..7886a70 100644 --- a/src/components/Score.js +++ b/src/components/Score.js @@ -1,7 +1,7 @@ import React from 'react'; import '../static/styles/score.scss'; -function Score({ score, categoryName, difficulty }) { +function Score({ score, categoryName, difficulty, totalQuestions, currentQuestion }) { return (
@@ -9,7 +9,9 @@ function Score({ score, categoryName, difficulty }) { Difficulty: {difficulty !== "" ? difficulty : "Easy"}
- Points: {score} + Points: {score} + {currentQuestion}/{totalQuestions} +
); diff --git a/src/containers/AnswersContainer.js b/src/containers/AnswersContainer.js index f6d3e38..502df5e 100644 --- a/src/containers/AnswersContainer.js +++ b/src/containers/AnswersContainer.js @@ -1,13 +1,15 @@ import { connect } from 'react-redux' import Answers from '../components/Answers'; -import { isRightAnswer, scoreUpdate, fetchQuestion } from '../actions'; +import { isRightAnswer, scoreUpdate, fetchQuestion, currentQuestion } from '../actions'; export const mapStateToProps = reduxStore => { return { answers: reduxStore.quizQuestion, score: reduxStore.score, category: reduxStore.optionsCategory, - difficulty: reduxStore.optionsDifficulty + difficulty: reduxStore.optionsDifficulty, + currentQuestion: reduxStore.currentQuestion, + totalQuestions: reduxStore.updateReduxQuestionsAmount }; }; @@ -15,7 +17,8 @@ const mapDispatchToProps = dispatch => { return { requestQuestion: (category, difficulty) => dispatch(fetchQuestion(category, difficulty)), scoreUpdate: score => dispatch(scoreUpdate(score)), - isRightAnswer: isRight => dispatch(isRightAnswer(isRight)) + isRightAnswer: isRight => dispatch(isRightAnswer(isRight)), + incrementCurrentQuestion: current => dispatch(currentQuestion(current)) } }; diff --git a/src/containers/ButtonSkipQuestionContainer.js b/src/containers/ButtonSkipQuestionContainer.js index 392366e..60fd49f 100644 --- a/src/containers/ButtonSkipQuestionContainer.js +++ b/src/containers/ButtonSkipQuestionContainer.js @@ -3,14 +3,17 @@ import ButtonSkipQuestion from '../components/ButtonSkipQuestion'; import { fetchQuestion, isRightAnswer, - scoreUpdate + scoreUpdate, + currentQuestion } from '../actions'; export const mapStateToProps = reduxStore => { return { score: reduxStore.score, category: reduxStore.optionsCategory, - difficulty: reduxStore.optionsDifficulty + difficulty: reduxStore.optionsDifficulty, + currentQuestion: reduxStore.currentQuestion, + totalQuestions: reduxStore.updateReduxQuestionsAmount }; }; @@ -18,7 +21,8 @@ const mapDispatchToProps = dispatch => { return { scoreUpdate: score => dispatch(scoreUpdate(score)), isRightAnswer: isRight => dispatch(isRightAnswer(isRight)), - requestQuestion: (category, difficulty) => dispatch(fetchQuestion(category, difficulty)) + requestQuestion: (category, difficulty) => dispatch(fetchQuestion(category, difficulty)), + incrementCurrentQuestion: current => dispatch(currentQuestion(current)) } }; diff --git a/src/containers/OptionsContainer.js b/src/containers/OptionsContainer.js index bc9b29a..c34e376 100644 --- a/src/containers/OptionsContainer.js +++ b/src/containers/OptionsContainer.js @@ -1,19 +1,28 @@ import { connect } from 'react-redux' import Options from '../components/Options'; -import { fetchQuestion, optionsDifficulty, optionsCategory, optionsCategoryName } from '../actions'; +import { + fetchQuestion, + optionsDifficulty, + optionsCategory, + optionsCategoryName, + updateReduxQuestionsAmount, + currentQuestion +} from '../actions'; -// export const mapStateToProps = reduxStore => { -// return { -// quizQuestion: reduxStore.quizQuestion -// }; -// }; +export const mapStateToProps = reduxStore => { + return { + currentQuestionValue: reduxStore.currentQuestion + }; +}; const mapDispatchToProps = dispatch => { return { - requestQuestionsUpdate: (category, difficulty) => dispatch(fetchQuestion(category, difficulty)), + requestQuestionsUpdate: (category, difficulty, amount) => dispatch(fetchQuestion(category, difficulty, amount)), optionsDifficulty: difficulty => dispatch(optionsDifficulty(difficulty)), optionsCategory: category => dispatch(optionsCategory(category)), - optionsCategoryName: categoryName => dispatch(optionsCategoryName(categoryName)) + optionsCategoryName: categoryName => dispatch(optionsCategoryName(categoryName)), + updateReduxQuestionsAmount: questionsAmount => dispatch(updateReduxQuestionsAmount(questionsAmount)), + currentQuestion: questionsCount => dispatch(currentQuestion(questionsCount)) } }; diff --git a/src/containers/QuestionContainer.js b/src/containers/QuestionContainer.js index 6abbd76..a89a6c3 100644 --- a/src/containers/QuestionContainer.js +++ b/src/containers/QuestionContainer.js @@ -4,7 +4,8 @@ import { fetchQuestion } from '../actions'; export const mapStateToProps = reduxStore => { return { - quizQuestion: reduxStore.quizQuestion + quizQuestion: reduxStore.quizQuestion, + currentQuestion: reduxStore.currentQuestion }; }; diff --git a/src/containers/ScoreContainer.js b/src/containers/ScoreContainer.js index ad72b72..7f63ec0 100644 --- a/src/containers/ScoreContainer.js +++ b/src/containers/ScoreContainer.js @@ -7,7 +7,9 @@ export const mapStateToProps = reduxStore => { return { score: reduxStore.score, categoryName: reduxStore.optionsCategoryName, - difficulty: reduxStore.optionsDifficulty + difficulty: reduxStore.optionsDifficulty, + totalQuestions: reduxStore.updateReduxQuestionsAmount, + currentQuestion: reduxStore.currentQuestion }; }; diff --git a/src/reducers/currentQuestion.js b/src/reducers/currentQuestion.js new file mode 100644 index 0000000..2439be7 --- /dev/null +++ b/src/reducers/currentQuestion.js @@ -0,0 +1,11 @@ +function currentQuestion( + state = 1, action) { + switch (action.type) { + case 'RECEIVE_CURRENT_QUESTION': + return action.currentQuestion + default: + return state + } +} + +export default currentQuestion; \ No newline at end of file diff --git a/src/reducers/index.js b/src/reducers/index.js index 756eed7..6c9b398 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -5,6 +5,8 @@ import score from './score'; import optionsDifficulty from './optionsDifficulty'; import optionsCategory from './optionsCategory'; import optionsCategoryName from './optionsCategoryName'; +import currentQuestion from './currentQuestion'; +import updateReduxQuestionsAmount from './updateReduxQuestionsAmount'; export default combineReducers({ quizQuestion, @@ -12,5 +14,7 @@ export default combineReducers({ score, optionsDifficulty, optionsCategory, - optionsCategoryName + optionsCategoryName, + currentQuestion, + updateReduxQuestionsAmount }); diff --git a/src/reducers/updateReduxQuestionsAmount.js b/src/reducers/updateReduxQuestionsAmount.js new file mode 100644 index 0000000..79c0a9d --- /dev/null +++ b/src/reducers/updateReduxQuestionsAmount.js @@ -0,0 +1,11 @@ +function updateReduxQuestionsAmount( + state = 10, action) { + switch (action.type) { + case 'RECEIVE_QUESTION_AMOUNT': + return action.updateReduxQuestionsAmount + default: + return state + } +} + +export default updateReduxQuestionsAmount; \ No newline at end of file diff --git a/src/static/styles/buttonSkipQuestion.scss b/src/static/styles/buttonSkipQuestion.scss index 9661e02..4f52c04 100644 --- a/src/static/styles/buttonSkipQuestion.scss +++ b/src/static/styles/buttonSkipQuestion.scss @@ -14,4 +14,8 @@ opacity: .8; } } + + &.skip-question--hidden { + display: none; + } } \ No newline at end of file diff --git a/src/static/styles/score.scss b/src/static/styles/score.scss index e701778..08283dd 100644 --- a/src/static/styles/score.scss +++ b/src/static/styles/score.scss @@ -8,8 +8,8 @@ .score__text { display: flex; - align-items: center; - justify-content: center; + flex-direction: column; + text-align: right; } .category { From 552bdca4e45f7ba8b5e66fe9c7a38184d9e06bea Mon Sep 17 00:00:00 2001 From: Ralph Date: Mon, 16 Jul 2018 08:51:34 +0100 Subject: [PATCH 14/24] Display message --- src/actions/index.js | 7 +++++++ src/components/Answers.js | 18 ++++++++++++------ src/components/Message.js | 20 ++++++++++++++++---- src/containers/AnswersContainer.js | 5 +++-- src/containers/MessageContainer.js | 13 +++++++++++-- src/reducers/index.js | 4 +++- src/reducers/score.js | 2 +- src/reducers/viewMessage.js | 10 ++++++++++ src/static/styles/message.scss | 28 +++++++++++++++++++++++----- 9 files changed, 86 insertions(+), 21 deletions(-) create mode 100644 src/reducers/viewMessage.js diff --git a/src/actions/index.js b/src/actions/index.js index 700fb6e..b5cad65 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -55,6 +55,13 @@ export function updateReduxQuestionsAmount(questionsAmount) { } } +export function viewMessage(viewMessage) { + return { + type: 'RECEIVE_VIEW_MESSAGE', + viewMessage + } +} + export function fetchQuestion(category = '', difficulty = '', amount = 1) { return function (dispatch) { fetch(`https://opentdb.com/api.php?amount=${amount}&type=multiple&category=${category}&difficulty=${difficulty}&encode=url3986`) diff --git a/src/components/Answers.js b/src/components/Answers.js index d98aa8b..47cdf10 100644 --- a/src/components/Answers.js +++ b/src/components/Answers.js @@ -12,7 +12,8 @@ function Answers({ difficulty, incrementCurrentQuestion, currentQuestion, - totalQuestions + totalQuestions, + viewMessage }) { const question_answers = answers @@ -23,19 +24,25 @@ function Answers({ function verifyAnswer(e, answer) { e.preventDefault(); - if (currentQuestion === +totalQuestions) return; + if (answer === answers.results[0].correct_answer) { isRightAnswer(true); - scoreUpdate(score + 10); e.target.classList.add('animated', 'pulse', 'answers__button--correct-answer'); + scoreUpdate(score + 10); + incrementCurrentQuestion(currentQuestion + 1); setTimeout(() => { isRightAnswer(false); }, 2000) + viewMessage(true); + if (currentQuestion === +totalQuestions) return; } else { - isRightAnswer(false); - scoreUpdate(score - 10); e.target.classList.add('animated', 'shake', 'answers__button--wrong-answer'); + scoreUpdate(score - 10); + isRightAnswer(false); + incrementCurrentQuestion(currentQuestion + 1); e.target.setAttribute("disabled", "disabled"); + viewMessage(true); + if (currentQuestion === +totalQuestions) { isRightAnswer(true); return }; } } @@ -50,7 +57,6 @@ function Answers({ requestQuestion(category, difficulty); isRightAnswer(false); }, 2000) - incrementCurrentQuestion(currentQuestion + 1); } } diff --git a/src/components/Message.js b/src/components/Message.js index 8110b52..59b9197 100644 --- a/src/components/Message.js +++ b/src/components/Message.js @@ -2,16 +2,28 @@ import React from 'react'; import '../static/styles/message.scss'; import cx from 'classnames'; -function Message({ questionAnswer }) { +function Message({ questionAnswer, score, viewMessage, updateMessage }) { const CSSClasses = cx('message ', { - visible: questionAnswer, + visible: viewMessage, animated: questionAnswer, fadeIn: questionAnswer, }); + const CoverClasses = cx('cover ', { + visible: viewMessage + }); + + setTimeout(() => { + updateMessage(false); + }, 3000); + return ( -
- {questionAnswer ? "Correct!" : ""} +
+
+ {questionAnswer ? "+ 10 points!" : "- 10 points!"} +
+
+ ); } diff --git a/src/containers/AnswersContainer.js b/src/containers/AnswersContainer.js index 502df5e..78bc6c6 100644 --- a/src/containers/AnswersContainer.js +++ b/src/containers/AnswersContainer.js @@ -1,6 +1,6 @@ import { connect } from 'react-redux' import Answers from '../components/Answers'; -import { isRightAnswer, scoreUpdate, fetchQuestion, currentQuestion } from '../actions'; +import { viewMessage, isRightAnswer, scoreUpdate, fetchQuestion, currentQuestion } from '../actions'; export const mapStateToProps = reduxStore => { return { @@ -18,7 +18,8 @@ const mapDispatchToProps = dispatch => { requestQuestion: (category, difficulty) => dispatch(fetchQuestion(category, difficulty)), scoreUpdate: score => dispatch(scoreUpdate(score)), isRightAnswer: isRight => dispatch(isRightAnswer(isRight)), - incrementCurrentQuestion: current => dispatch(currentQuestion(current)) + incrementCurrentQuestion: current => dispatch(currentQuestion(current)), + viewMessage: isVisible => dispatch(viewMessage(isVisible)) } }; diff --git a/src/containers/MessageContainer.js b/src/containers/MessageContainer.js index 51bccb4..2c8ac67 100644 --- a/src/containers/MessageContainer.js +++ b/src/containers/MessageContainer.js @@ -1,14 +1,23 @@ import React from 'react'; import { connect } from 'react-redux'; import Message from '../components/Message'; +import { viewMessage } from '../actions'; export const mapStateToProps = reduxStore => { return { - questionAnswer: reduxStore.quizAnswer + questionAnswer: reduxStore.quizAnswer, + score: reduxStore.score, + viewMessage: reduxStore.viewMessage } } +const mapDispatchToProps = dispatch => { + return { + updateMessage: isVisible => dispatch(viewMessage(isVisible)) + } +}; + export default connect( mapStateToProps, - null + mapDispatchToProps )(Message); \ No newline at end of file diff --git a/src/reducers/index.js b/src/reducers/index.js index 6c9b398..4e48fb5 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -7,6 +7,7 @@ import optionsCategory from './optionsCategory'; import optionsCategoryName from './optionsCategoryName'; import currentQuestion from './currentQuestion'; import updateReduxQuestionsAmount from './updateReduxQuestionsAmount'; +import viewMessage from './viewMessage'; export default combineReducers({ quizQuestion, @@ -16,5 +17,6 @@ export default combineReducers({ optionsCategory, optionsCategoryName, currentQuestion, - updateReduxQuestionsAmount + updateReduxQuestionsAmount, + viewMessage }); diff --git a/src/reducers/score.js b/src/reducers/score.js index f6c56dd..b5b1daf 100644 --- a/src/reducers/score.js +++ b/src/reducers/score.js @@ -1,4 +1,4 @@ -function score(score = 50, action) { +function score(score = 0, action) { switch (action.type) { case 'RECEIVE_SCORE': return action.score diff --git a/src/reducers/viewMessage.js b/src/reducers/viewMessage.js new file mode 100644 index 0000000..47c5557 --- /dev/null +++ b/src/reducers/viewMessage.js @@ -0,0 +1,10 @@ +function viewMessage(state = false, action) { + switch (action.type) { + case 'RECEIVE_VIEW_MESSAGE': + return action.viewMessage + default: + return state + } +} + +export default viewMessage; \ No newline at end of file diff --git a/src/static/styles/message.scss b/src/static/styles/message.scss index 358e4ea..acb7d0c 100644 --- a/src/static/styles/message.scss +++ b/src/static/styles/message.scss @@ -6,6 +6,7 @@ font-size: 36px; transform: rotate(-4deg) translate(-50%, -60%); font-family: 'Bitter', serif; + z-index: 2; background-color: #fcaa02; width: 150px; @@ -14,9 +15,9 @@ z-index: 9999; display: none; - // &.visible { - // display: block; - // } + &.visible { + display: block; + } &:after { content: ""; @@ -45,7 +46,24 @@ .message__text { z-index: 99999; position: absolute; - top: 33%; - left: 6%; + top: 20%; + left: 4%; + text-align: center; + } +} + +.cover { + position: fixed; + background-color: var(--primary-color); + opacity: .1; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1; + display: none; + + &.visible { + display: block; } } \ No newline at end of file From e89b72b93e892d9c03709ce8056edcaf84f77e40 Mon Sep 17 00:00:00 2001 From: Ralph Date: Mon, 16 Jul 2018 08:54:12 +0100 Subject: [PATCH 15/24] Reset points on options update --- src/components/Options.js | 1 + src/containers/OptionsContainer.js | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/Options.js b/src/components/Options.js index 6f14ad7..7c2cc9e 100644 --- a/src/components/Options.js +++ b/src/components/Options.js @@ -153,6 +153,7 @@ class Options extends React.Component { onClick={(e) => { this.props.requestQuestionsUpdate(this.state.category, this.state.difficulty, 1); this.props.currentQuestion(1); + this.props.scoreUpdate(0); this.toggleOptions(); this.updateReduxCategory(e); this.updateReduxDifficulty(e); diff --git a/src/containers/OptionsContainer.js b/src/containers/OptionsContainer.js index c34e376..cf12619 100644 --- a/src/containers/OptionsContainer.js +++ b/src/containers/OptionsContainer.js @@ -6,7 +6,8 @@ import { optionsCategory, optionsCategoryName, updateReduxQuestionsAmount, - currentQuestion + currentQuestion, + scoreUpdate } from '../actions'; export const mapStateToProps = reduxStore => { @@ -22,7 +23,8 @@ const mapDispatchToProps = dispatch => { optionsCategory: category => dispatch(optionsCategory(category)), optionsCategoryName: categoryName => dispatch(optionsCategoryName(categoryName)), updateReduxQuestionsAmount: questionsAmount => dispatch(updateReduxQuestionsAmount(questionsAmount)), - currentQuestion: questionsCount => dispatch(currentQuestion(questionsCount)) + currentQuestion: questionsCount => dispatch(currentQuestion(questionsCount)), + scoreUpdate: score => dispatch(scoreUpdate(score)) } }; From 0ad4472eaad8b476bbec08432efd20f807689219 Mon Sep 17 00:00:00 2001 From: Ralph Date: Mon, 16 Jul 2018 09:38:19 +0100 Subject: [PATCH 16/24] Added routing --- package-lock.json | 1383 +++++++++++++++++++++++++-------- package.json | 11 +- server.js | 24 + src/components/App.js | 34 +- src/index.js | 5 +- index.html => views/index.hbs | 0 6 files changed, 1108 insertions(+), 349 deletions(-) create mode 100644 server.js rename index.html => views/index.hbs (100%) diff --git a/package-lock.json b/package-lock.json index b3f8dea..d6d652a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -365,8 +365,16 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "requires": { + "mime-types": "~2.1.18", + "negotiator": "0.6.1" + } }, "acorn": { "version": "5.7.1", @@ -414,7 +422,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "dev": true, "requires": { "kind-of": "^3.0.2", "longest": "^1.0.1", @@ -425,7 +432,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -435,8 +441,15 @@ "amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true + "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=", + "requires": { + "string-width": "^2.0.0" + } }, "ansi-escapes": { "version": "3.1.0", @@ -466,7 +479,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, "requires": { "micromatch": "^3.1.4", "normalize-path": "^2.1.1" @@ -509,20 +521,17 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" }, "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" }, "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" }, "array-differ": { "version": "1.0.0", @@ -542,6 +551,11 @@ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", "dev": true }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", @@ -560,8 +574,7 @@ "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, "arrify": { "version": "1.0.1", @@ -626,8 +639,7 @@ "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" }, "ast-types": { "version": "0.11.5", @@ -653,8 +665,7 @@ "async-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=" }, "async-foreach": { "version": "0.1.3", @@ -677,8 +688,7 @@ "atob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz", - "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=", - "dev": true + "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=" }, "aws-sign2": { "version": "0.7.0", @@ -1686,14 +1696,12 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, "requires": { "cache-base": "^1.0.1", "class-utils": "^0.3.5", @@ -1708,7 +1716,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -1717,7 +1724,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -1726,7 +1732,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -1735,7 +1740,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -1769,8 +1773,7 @@ "binary-extensions": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", - "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", - "dev": true + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=" }, "binaryextensions": { "version": "2.1.1", @@ -1799,6 +1802,23 @@ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", "dev": true }, + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + } + }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -1813,11 +1833,57 @@ "hoek": "2.x.x" } }, + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1827,7 +1893,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -1845,7 +1910,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -1998,6 +2062,11 @@ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, "cacache": { "version": "10.0.4", "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", @@ -2031,7 +2100,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, "requires": { "collection-visit": "^1.0.0", "component-emitter": "^1.2.1", @@ -2083,7 +2151,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true, "optional": true }, "camelcase-keys": { @@ -2119,6 +2186,11 @@ "rsvp": "^3.3.3" } }, + "capture-stack-trace": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", + "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=" + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -2129,7 +2201,6 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "dev": true, "optional": true, "requires": { "align-text": "^0.1.3", @@ -2172,7 +2243,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "dev": true, "requires": { "anymatch": "^2.0.0", "async-each": "^1.0.0", @@ -2193,7 +2263,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, "requires": { "is-glob": "^3.1.0", "path-dirname": "^1.0.0" @@ -2203,7 +2272,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, "requires": { "is-extglob": "^2.1.0" } @@ -2213,14 +2281,12 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-glob": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -2245,8 +2311,7 @@ "ci-info": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.3.tgz", - "integrity": "sha512-SK/846h/Rcy8q9Z9CAwGBLfCJ6EkjJWdpelWDufQpqVDYq2Wnnv8zlSO6AMQap02jvhVruKKpEtQOufo3pFhLg==", - "dev": true + "integrity": "sha512-SK/846h/Rcy8q9Z9CAwGBLfCJ6EkjJWdpelWDufQpqVDYq2Wnnv8zlSO6AMQap02jvhVruKKpEtQOufo3pFhLg==" }, "cipher-base": { "version": "1.0.4", @@ -2262,7 +2327,6 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, "requires": { "arr-union": "^3.1.0", "define-property": "^0.2.5", @@ -2274,7 +2338,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -2286,6 +2349,11 @@ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" + }, "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", @@ -2360,7 +2428,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, "optional": true, "requires": { "center-align": "^0.1.1", @@ -2372,7 +2439,6 @@ "version": "0.0.2", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true, "optional": true } } @@ -2454,7 +2520,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, "requires": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" @@ -2464,7 +2529,6 @@ "version": "1.9.2", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", - "dev": true, "requires": { "color-name": "1.1.1" } @@ -2472,8 +2536,7 @@ "color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=", - "dev": true + "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=" }, "colors": { "version": "0.5.1", @@ -2510,14 +2573,12 @@ "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 + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { "version": "1.6.2", @@ -2531,6 +2592,19 @@ "typedarray": "^0.0.6" } }, + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, "console-browserify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", @@ -2552,12 +2626,32 @@ "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", "dev": true }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, "convert-source-map": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", "dev": true }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, "copy-concurrently": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", @@ -2575,8 +2669,7 @@ "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, "core-js": { "version": "1.2.7", @@ -2598,6 +2691,14 @@ "elliptic": "^6.0.0" } }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, "create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", @@ -2629,7 +2730,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, "requires": { "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", @@ -2664,6 +2764,11 @@ "randomfill": "^1.0.3" } }, + "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=" + }, "css-loader": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-1.0.0.tgz", @@ -2808,7 +2913,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -2816,14 +2920,12 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" }, "decompress-response": { "version": "3.3.0", @@ -2837,8 +2939,7 @@ "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, "deep-is": { "version": "0.1.3", @@ -2876,7 +2977,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, "requires": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" @@ -2886,7 +2986,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -2895,7 +2994,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -2904,7 +3002,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -2925,6 +3022,11 @@ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, "des.js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", @@ -2935,6 +3037,11 @@ "minimalistic-assert": "^1.0.0" } }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, "detect-conflict": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/detect-conflict/-/detect-conflict-1.0.1.tgz", @@ -3058,11 +3165,23 @@ "domelementtype": "1" } }, + "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==", + "requires": { + "is-obj": "^1.0.0" + } + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" + }, "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" }, "duplexify": { "version": "3.6.0", @@ -3092,6 +3211,11 @@ "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==", "dev": true }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, "ejs": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz", @@ -3131,6 +3255,11 @@ "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", "dev": true }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, "encoding": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", @@ -3266,11 +3395,15 @@ "is-symbol": "^1.0.1" } }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "escodegen": { "version": "1.10.0", @@ -3337,6 +3470,25 @@ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "event-stream": { + "version": "3.3.4", + "resolved": "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "requires": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" + } + }, "events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", @@ -3366,7 +3518,6 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, "requires": { "cross-spawn": "^5.0.1", "get-stream": "^3.0.0", @@ -3393,7 +3544,6 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, "requires": { "debug": "^2.3.3", "define-property": "^0.2.5", @@ -3408,7 +3558,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -3417,7 +3566,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -3509,6 +3657,116 @@ } } }, + "express": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", + "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", + "requires": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.2", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.3", + "qs": "6.5.1", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.1", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "requires": { + "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.5.1", + "raw-body": "2.3.2", + "type-is": "~1.6.15" + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + }, + "dependencies": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" + }, + "http-errors": { + "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.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": ">= 1.3.1 < 2" + } + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" + } + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + } + } + }, "extend": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", @@ -3519,7 +3777,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -3529,7 +3786,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, "requires": { "is-plain-object": "^2.0.4" } @@ -3551,7 +3807,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, "requires": { "array-unique": "^0.3.2", "define-property": "^1.0.0", @@ -3567,7 +3822,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -3576,7 +3830,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -3585,7 +3838,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -3594,7 +3846,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -3603,7 +3854,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -3746,7 +3996,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -3758,13 +4007,26 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } } } }, + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" + } + }, "find-cache-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", @@ -3813,8 +4075,7 @@ "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" }, "for-own": { "version": "0.1.5", @@ -3830,6 +4091,11 @@ "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" }, + "foreachasync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/foreachasync/-/foreachasync-3.0.0.tgz", + "integrity": "sha1-VQKYfchxS+M5IJfzLgBxyd7gfPY=" + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -3847,15 +4113,29 @@ "mime-types": "^2.1.12" } }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, "requires": { "map-cache": "^0.2.2" } }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=" + }, "from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", @@ -3888,7 +4168,6 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", - "dev": true, "optional": true, "requires": { "nan": "^2.9.2", @@ -3898,24 +4177,20 @@ "abbrev": { "version": "1.1.1", "bundled": true, - "dev": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "bundled": true, - "dev": true + "bundled": true }, "aproba": { "version": "1.2.0", "bundled": true, - "dev": true, "optional": true }, "are-we-there-yet": { "version": "1.1.4", "bundled": true, - "dev": true, "optional": true, "requires": { "delegates": "^1.0.0", @@ -3924,13 +4199,11 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true, - "dev": true + "bundled": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3939,34 +4212,28 @@ "chownr": { "version": "1.0.1", "bundled": true, - "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "bundled": true, - "dev": true + "bundled": true }, "concat-map": { "version": "0.0.1", - "bundled": true, - "dev": true + "bundled": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, - "dev": true + "bundled": true }, "core-util-is": { "version": "1.0.2", "bundled": true, - "dev": true, "optional": true }, "debug": { "version": "2.6.9", "bundled": true, - "dev": true, "optional": true, "requires": { "ms": "2.0.0" @@ -3975,25 +4242,21 @@ "deep-extend": { "version": "0.5.1", "bundled": true, - "dev": true, "optional": true }, "delegates": { "version": "1.0.0", "bundled": true, - "dev": true, "optional": true }, "detect-libc": { "version": "1.0.3", "bundled": true, - "dev": true, "optional": true }, "fs-minipass": { "version": "1.2.5", "bundled": true, - "dev": true, "optional": true, "requires": { "minipass": "^2.2.1" @@ -4002,13 +4265,11 @@ "fs.realpath": { "version": "1.0.0", "bundled": true, - "dev": true, "optional": true }, "gauge": { "version": "2.7.4", "bundled": true, - "dev": true, "optional": true, "requires": { "aproba": "^1.0.3", @@ -4024,7 +4285,6 @@ "glob": { "version": "7.1.2", "bundled": true, - "dev": true, "optional": true, "requires": { "fs.realpath": "^1.0.0", @@ -4038,13 +4298,11 @@ "has-unicode": { "version": "2.0.1", "bundled": true, - "dev": true, "optional": true }, "iconv-lite": { "version": "0.4.21", "bundled": true, - "dev": true, "optional": true, "requires": { "safer-buffer": "^2.1.0" @@ -4053,7 +4311,6 @@ "ignore-walk": { "version": "3.0.1", "bundled": true, - "dev": true, "optional": true, "requires": { "minimatch": "^3.0.4" @@ -4062,7 +4319,6 @@ "inflight": { "version": "1.0.6", "bundled": true, - "dev": true, "optional": true, "requires": { "once": "^1.3.0", @@ -4071,19 +4327,16 @@ }, "inherits": { "version": "2.0.3", - "bundled": true, - "dev": true + "bundled": true }, "ini": { "version": "1.3.5", "bundled": true, - "dev": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, - "dev": true, "requires": { "number-is-nan": "^1.0.0" } @@ -4091,26 +4344,22 @@ "isarray": { "version": "1.0.0", "bundled": true, - "dev": true, "optional": true }, "minimatch": { "version": "3.0.4", "bundled": true, - "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true, - "dev": true + "bundled": true }, "minipass": { "version": "2.2.4", "bundled": true, - "dev": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -4119,7 +4368,6 @@ "minizlib": { "version": "1.1.0", "bundled": true, - "dev": true, "optional": true, "requires": { "minipass": "^2.2.1" @@ -4128,7 +4376,6 @@ "mkdirp": { "version": "0.5.1", "bundled": true, - "dev": true, "requires": { "minimist": "0.0.8" } @@ -4136,13 +4383,11 @@ "ms": { "version": "2.0.0", "bundled": true, - "dev": true, "optional": true }, "needle": { "version": "2.2.0", "bundled": true, - "dev": true, "optional": true, "requires": { "debug": "^2.1.2", @@ -4153,7 +4398,6 @@ "node-pre-gyp": { "version": "0.10.0", "bundled": true, - "dev": true, "optional": true, "requires": { "detect-libc": "^1.0.2", @@ -4171,7 +4415,6 @@ "nopt": { "version": "4.0.1", "bundled": true, - "dev": true, "optional": true, "requires": { "abbrev": "1", @@ -4181,13 +4424,11 @@ "npm-bundled": { "version": "1.0.3", "bundled": true, - "dev": true, "optional": true }, "npm-packlist": { "version": "1.1.10", "bundled": true, - "dev": true, "optional": true, "requires": { "ignore-walk": "^3.0.1", @@ -4197,7 +4438,6 @@ "npmlog": { "version": "4.1.2", "bundled": true, - "dev": true, "optional": true, "requires": { "are-we-there-yet": "~1.1.2", @@ -4208,19 +4448,16 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, - "dev": true + "bundled": true }, "object-assign": { "version": "4.1.1", "bundled": true, - "dev": true, "optional": true }, "once": { "version": "1.4.0", "bundled": true, - "dev": true, "requires": { "wrappy": "1" } @@ -4228,19 +4465,16 @@ "os-homedir": { "version": "1.0.2", "bundled": true, - "dev": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", "bundled": true, - "dev": true, "optional": true }, "osenv": { "version": "0.1.5", "bundled": true, - "dev": true, "optional": true, "requires": { "os-homedir": "^1.0.0", @@ -4250,19 +4484,16 @@ "path-is-absolute": { "version": "1.0.1", "bundled": true, - "dev": true, "optional": true }, "process-nextick-args": { "version": "2.0.0", "bundled": true, - "dev": true, "optional": true }, "rc": { "version": "1.2.7", "bundled": true, - "dev": true, "optional": true, "requires": { "deep-extend": "^0.5.1", @@ -4274,7 +4505,6 @@ "minimist": { "version": "1.2.0", "bundled": true, - "dev": true, "optional": true } } @@ -4282,7 +4512,6 @@ "readable-stream": { "version": "2.3.6", "bundled": true, - "dev": true, "optional": true, "requires": { "core-util-is": "~1.0.0", @@ -4297,7 +4526,6 @@ "rimraf": { "version": "2.6.2", "bundled": true, - "dev": true, "optional": true, "requires": { "glob": "^7.0.5" @@ -4305,43 +4533,36 @@ }, "safe-buffer": { "version": "5.1.1", - "bundled": true, - "dev": true + "bundled": true }, "safer-buffer": { "version": "2.1.2", "bundled": true, - "dev": true, "optional": true }, "sax": { "version": "1.2.4", "bundled": true, - "dev": true, "optional": true }, "semver": { "version": "5.5.0", "bundled": true, - "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", "bundled": true, - "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", "bundled": true, - "dev": true, "optional": true }, "string-width": { "version": "1.0.2", "bundled": true, - "dev": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -4351,7 +4572,6 @@ "string_decoder": { "version": "1.1.1", "bundled": true, - "dev": true, "optional": true, "requires": { "safe-buffer": "~5.1.0" @@ -4360,7 +4580,6 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -4368,13 +4587,11 @@ "strip-json-comments": { "version": "2.0.1", "bundled": true, - "dev": true, "optional": true }, "tar": { "version": "4.4.1", "bundled": true, - "dev": true, "optional": true, "requires": { "chownr": "^1.0.1", @@ -4389,13 +4606,11 @@ "util-deprecate": { "version": "1.0.2", "bundled": true, - "dev": true, "optional": true }, "wide-align": { "version": "1.1.2", "bundled": true, - "dev": true, "optional": true, "requires": { "string-width": "^1.0.2" @@ -4403,13 +4618,11 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, - "dev": true + "bundled": true }, "yallist": { "version": "3.0.2", - "bundled": true, - "dev": true + "bundled": true } } }, @@ -4502,14 +4715,12 @@ "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" }, "getpass": { "version": "0.1.7", @@ -4659,6 +4870,14 @@ "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", "dev": true }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "requires": { + "ini": "^1.3.4" + } + }, "global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", @@ -4759,8 +4978,7 @@ "graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, "grouped-queue": { "version": "0.3.3", @@ -4848,8 +5066,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-symbol-support-x": { "version": "1.4.2", @@ -4881,7 +5098,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, "requires": { "get-value": "^2.0.6", "has-values": "^1.0.0", @@ -4892,7 +5108,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, "requires": { "is-number": "^3.0.0", "kind-of": "^4.0.0" @@ -4902,7 +5117,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -4941,6 +5155,63 @@ "sntp": "1.x.x" } }, + "hbs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/hbs/-/hbs-4.0.1.tgz", + "integrity": "sha1-S/2YZQ3IydrESzyprfnAmOi8M7Y=", + "requires": { + "handlebars": "4.0.5", + "walk": "2.3.9" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + }, + "handlebars": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.5.tgz", + "integrity": "sha1-ksbta7FkEQxQ1NjQ+93HCAbG+Oc=", + "requires": { + "async": "^1.4.0", + "optimist": "^0.6.1", + "source-map": "^0.4.4", + "uglify-js": "^2.6" + } + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "history": { + "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.1", + "loose-envify": "^1.2.0", + "resolve-pathname": "^2.2.0", + "value-equal": "^0.4.0", + "warning": "^3.0.0" + }, + "dependencies": { + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -5016,6 +5287,17 @@ "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", "dev": true }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -5074,6 +5356,16 @@ "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", "dev": true }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" + }, "import-local": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz", @@ -5087,8 +5379,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, "in-publish": { "version": "2.0.0", @@ -5129,8 +5420,7 @@ "ini": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, "inquirer": { "version": "5.2.0", @@ -5229,11 +5519,15 @@ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true }, + "ipaddr.js": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", + "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=" + }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, "requires": { "kind-of": "^3.0.2" }, @@ -5242,7 +5536,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -5259,7 +5552,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, "requires": { "binary-extensions": "^1.0.0" } @@ -5272,8 +5564,7 @@ "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-builtin-module": { "version": "1.0.0", @@ -5293,7 +5584,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz", "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==", - "dev": true, "requires": { "ci-info": "^1.0.0" } @@ -5302,7 +5592,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, "requires": { "kind-of": "^3.0.2" }, @@ -5311,7 +5600,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -5327,7 +5615,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -5337,8 +5624,7 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" } } }, @@ -5360,8 +5646,7 @@ "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" }, "is-extglob": { "version": "1.0.0", @@ -5381,8 +5666,7 @@ "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 + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "is-generator-fn": { "version": "1.0.0", @@ -5399,11 +5683,24 @@ "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=", + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=" + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, "requires": { "kind-of": "^3.0.2" }, @@ -5412,7 +5709,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -5424,6 +5720,11 @@ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.3.tgz", "integrity": "sha1-8mWrian0RQNO9q/xWo8AsA9VF5k=" }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + }, "is-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", @@ -5439,6 +5740,14 @@ "symbol-observable": "^1.1.0" } }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "requires": { + "path-is-inside": "^1.0.1" + } + }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -5449,7 +5758,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, "requires": { "isobject": "^3.0.1" } @@ -5472,6 +5780,11 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" + }, "is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", @@ -5483,8 +5796,7 @@ "is-retry-allowed": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", - "dev": true + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" }, "is-scoped": { "version": "1.0.0", @@ -5530,8 +5842,7 @@ "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" }, "isarray": { "version": "1.0.0", @@ -5547,14 +5858,12 @@ "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", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, "isomorphic-fetch": { "version": "2.2.1", @@ -7036,14 +7345,20 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "requires": { + "package-json": "^4.0.0" + } }, "lazy-cache": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true, "optional": true }, "lcid": { @@ -7300,8 +7615,7 @@ "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" }, "lodash.flattendeep": { "version": "4.4.0", @@ -7418,8 +7732,7 @@ "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" }, "loose-envify": { "version": "1.4.0", @@ -7442,14 +7755,12 @@ "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" }, "lru-cache": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", - "dev": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" @@ -7459,7 +7770,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, "requires": { "pify": "^3.0.0" }, @@ -7467,8 +7777,7 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" } } }, @@ -7490,8 +7799,7 @@ "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" }, "map-obj": { "version": "1.0.1", @@ -7499,11 +7807,15 @@ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", "dev": true }, + "map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=" + }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, "requires": { "object-visit": "^1.0.0" } @@ -7524,6 +7836,11 @@ "inherits": "^2.0.1" } }, + "media-typer": { + "version": "0.3.0", + "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", @@ -7659,6 +7976,11 @@ "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=", "dev": true }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, "merge-stream": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", @@ -7674,11 +7996,15 @@ "integrity": "sha512-bgM8twH86rWni21thii6WCMQMRMmwqqdW3sGWi9IipnVAszdLXRjwDwAnyrVXo6DuP3AjRMMttZKUB48QWIFGg==", "dev": true }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -7705,17 +8031,20 @@ "brorand": "^1.0.1" } }, + "mime": { + "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.33.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" }, "mime-types": { "version": "2.1.18", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, "requires": { "mime-db": "~1.33.0" } @@ -7748,7 +8077,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -7756,8 +8084,7 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "mississippi": { "version": "2.0.0", @@ -7781,7 +8108,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", - "dev": true, "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" @@ -7791,7 +8117,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, "requires": { "is-plain-object": "^2.0.4" } @@ -7842,8 +8167,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "multimatch": { "version": "2.1.0", @@ -7866,14 +8190,12 @@ "nan": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -7905,6 +8227,11 @@ "semver": "^5.4.1" } }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, "neo-async": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.1.tgz", @@ -8173,6 +8500,41 @@ } } }, + "nodemon": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.18.2.tgz", + "integrity": "sha512-FKuvzVurERMgX231T9KexWWWopjd93vapFY8rLn2JlPZ58uCW2s7U8utKElpGUEAqU5Y33///KFza5O9ndVRHQ==", + "requires": { + "chokidar": "^2.0.2", + "debug": "^3.1.0", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.0", + "semver": "^5.5.0", + "supports-color": "^5.2.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.2", + "update-notifier": "^2.3.0" + }, + "dependencies": { + "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" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "nomnom": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.6.2.tgz", @@ -8207,7 +8569,6 @@ "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.1" } @@ -8227,7 +8588,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, "requires": { "path-key": "^2.0.0" } @@ -8279,7 +8639,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, "requires": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", @@ -8290,7 +8649,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -8299,7 +8657,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -8325,7 +8682,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, "requires": { "isobject": "^3.0.0" } @@ -8376,7 +8732,6 @@ "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": "^3.0.1" } @@ -8392,6 +8747,14 @@ "has": "^1.0.1" } }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -8414,7 +8777,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, "requires": { "minimist": "~0.0.1", "wordwrap": "~0.0.2" @@ -8538,8 +8900,7 @@ "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "p-is-promise": { "version": "1.1.0", @@ -8598,6 +8959,50 @@ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + }, + "dependencies": { + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + } + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "requires": { + "prepend-http": "^1.0.1" + } + } + } + }, "pako": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", @@ -8663,11 +9068,15 @@ "@types/node": "*" } }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" }, "path-browserify": { "version": "0.0.0", @@ -8678,8 +9087,7 @@ "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" }, "path-exists": { "version": "3.0.0", @@ -8690,14 +9098,17 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, "path-parse": { "version": "1.0.5", @@ -8705,6 +9116,21 @@ "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", "dev": true }, + "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" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + } + } + }, "path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", @@ -8716,6 +9142,14 @@ "pinkie-promise": "^2.0.0" } }, + "pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "requires": { + "through": "~2.3" + } + }, "pbkdf2": { "version": "3.0.16", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", @@ -8773,8 +9207,7 @@ "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, "postcss": { "version": "6.0.23", @@ -8966,17 +9399,33 @@ "object-assign": "^4.1.1" } }, + "proxy-addr": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", + "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.6.0" + } + }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "dev": true }, + "ps-tree": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz", + "integrity": "sha1-tCGyQUDWID8e08dplrRCewjowBQ=", + "requires": { + "event-stream": "~3.3.0" + } + }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { "version": "1.1.28", @@ -8984,6 +9433,14 @@ "integrity": "sha512-+AqO1Ae+N/4r7Rvchrdm432afjT9hqJRyBN3DQv9At0tPz4hIFSGKbq64fN9dVoCow4oggIIax5/iONx0r9hZw==", "dev": true }, + "pstree.remy": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.0.tgz", + "integrity": "sha512-q5I5vLRMVtdWa8n/3UEzZX7Lfghzrg9eG2IKk2ENLSofKRCXVqMvMUHxCKgXNaqH/8ebhBxrqftHWnyTFweJ5Q==", + "requires": { + "ps-tree": "^1.1.0" + } + }, "public-encrypt": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", @@ -9027,8 +9484,7 @@ "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "query-string": { "version": "5.1.1", @@ -9113,6 +9569,40 @@ "safe-buffer": "^5.1.0" } }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, "react": { "version": "16.4.1", "resolved": "https://registry.npmjs.org/react/-/react-16.4.1.tgz", @@ -9164,6 +9654,33 @@ "prop-types": "^15.6.0" } }, + "react-router": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz", + "integrity": "sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg==", + "requires": { + "history": "^4.7.2", + "hoist-non-react-statics": "^2.5.0", + "invariant": "^2.2.4", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.1", + "warning": "^4.0.1" + } + }, + "react-router-dom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-4.3.1.tgz", + "integrity": "sha512-c/MlywfxDdCp7EnB7YfPMOfMD3tOtIjrQlj/CKfNMBxdmpJP8xcz5P/UAFn3JbnQCNUxsHyVVqllF9LhgVyFCA==", + "requires": { + "history": "^4.7.2", + "invariant": "^2.2.4", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.1", + "react-router": "^4.3.1", + "warning": "^4.0.1" + } + }, "react-test-renderer": { "version": "16.4.1", "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.4.1.tgz", @@ -9253,7 +9770,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", - "dev": true, "requires": { "graceful-fs": "^4.1.2", "minimatch": "^3.0.2", @@ -9359,7 +9875,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, "requires": { "extend-shallow": "^3.0.2", "safe-regex": "^1.1.0" @@ -9376,6 +9891,23 @@ "regjsparser": "^0.1.4" } }, + "registry-auth-token": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", + "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "requires": { + "rc": "^1.0.1" + } + }, "regjsgen": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", @@ -9402,20 +9934,17 @@ "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" }, "repeat-element": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=" }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, "repeating": { "version": "2.0.1", @@ -9540,11 +10069,15 @@ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", "dev": true }, + "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", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" }, "responselike": { "version": "1.0.2", @@ -9574,7 +10107,6 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "dev": true, "optional": true, "requires": { "align-text": "^0.1.1" @@ -9658,7 +10190,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, "requires": { "ret": "~0.1.10" } @@ -9884,12 +10415,51 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" }, + "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.0.3" + } + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + } + }, "serialize-javascript": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.5.0.tgz", "integrity": "sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ==", "dev": true }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -9899,14 +10469,12 @@ "set-immediate-shim": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" }, "set-value": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "dev": true, "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -9918,7 +10486,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -9930,6 +10497,11 @@ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, "sha.js": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", @@ -9963,7 +10535,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, "requires": { "shebang-regex": "^1.0.0" } @@ -9971,8 +10542,7 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" }, "shelljs": { "version": "0.8.2", @@ -9994,8 +10564,7 @@ "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "slash": { "version": "1.0.0", @@ -10019,7 +10588,6 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, "requires": { "base": "^0.11.1", "debug": "^2.2.0", @@ -10035,7 +10603,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -10044,7 +10611,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -10055,7 +10621,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, "requires": { "define-property": "^1.0.0", "isobject": "^3.0.0", @@ -10066,7 +10631,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -10075,7 +10639,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -10084,7 +10647,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -10093,7 +10655,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -10106,7 +10667,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, "requires": { "kind-of": "^3.2.0" }, @@ -10115,7 +10675,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -10149,14 +10708,12 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" }, "source-map-resolve": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, "requires": { "atob": "^2.1.1", "decode-uri-component": "^0.2.0", @@ -10186,8 +10743,7 @@ "source-map-url": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, "spdx-correct": { "version": "3.0.0", @@ -10221,11 +10777,18 @@ "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", "dev": true }, + "split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "requires": { + "through": "2" + } + }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, "requires": { "extend-shallow": "^3.0.0" } @@ -10272,7 +10835,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, "requires": { "define-property": "^0.2.5", "object-copy": "^0.1.0" @@ -10282,13 +10844,17 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } } } }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + }, "stdout-stream": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz", @@ -10314,6 +10880,14 @@ "readable-stream": "^2.0.2" } }, + "stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "requires": { + "duplexer": "~0.1.1" + } + }, "stream-each": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz", @@ -10386,7 +10960,6 @@ "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" @@ -10395,14 +10968,12 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "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" } @@ -10454,8 +11025,7 @@ "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, "strip-indent": { "version": "1.0.1", @@ -10466,6 +11036,11 @@ "get-stdin": "^4.0.1" } }, + "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=" + }, "style-loader": { "version": "0.21.0", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.21.0.tgz", @@ -10528,6 +11103,14 @@ } } }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "requires": { + "execa": "^0.7.0" + } + }, "test-exclude": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.2.1.tgz", @@ -10562,8 +11145,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { "version": "2.0.3", @@ -10578,8 +11160,7 @@ "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 + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" }, "timers-browserify": { "version": "2.0.10", @@ -10621,7 +11202,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, "requires": { "kind-of": "^3.0.2" }, @@ -10630,7 +11210,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -10641,7 +11220,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, "requires": { "define-property": "^2.0.2", "extend-shallow": "^3.0.2", @@ -10653,12 +11231,29 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" } }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "requires": { + "nopt": "~1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "requires": { + "abbrev": "1" + } + } + } + }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", @@ -10759,6 +11354,15 @@ "prelude-ls": "~1.1.2" } }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + } + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -10774,7 +11378,6 @@ "version": "2.8.29", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "dev": true, "optional": true, "requires": { "source-map": "~0.5.1", @@ -10786,7 +11389,6 @@ "version": "3.10.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, "optional": true, "requires": { "camelcase": "^1.0.2", @@ -10801,7 +11403,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "dev": true, "optional": true }, "uglifyjs-webpack-plugin": { @@ -10838,6 +11439,14 @@ } } }, + "undefsafe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", + "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", + "requires": { + "debug": "^2.2.0" + } + }, "underscore": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz", @@ -10847,7 +11456,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "dev": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", @@ -10859,7 +11467,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -10868,7 +11475,6 @@ "version": "0.4.3", "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -10896,11 +11502,23 @@ "imurmurhash": "^0.1.4" } }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "requires": { + "crypto-random-string": "^1.0.0" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, "requires": { "has-value": "^0.3.1", "isobject": "^3.0.0" @@ -10910,7 +11528,6 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, "requires": { "get-value": "^2.0.3", "has-values": "^0.1.4", @@ -10921,7 +11538,6 @@ "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" } @@ -10931,8 +11547,7 @@ "has-values": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" } } }, @@ -10942,11 +11557,60 @@ "integrity": "sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA==", "dev": true }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=" + }, "upath": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", - "dev": true + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==" + }, + "update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "requires": { + "has-flag": "^3.0.0" + } + } + } }, "uri-js": { "version": "4.2.2", @@ -10960,8 +11624,7 @@ "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" }, "url": { "version": "0.11.0", @@ -10999,8 +11662,7 @@ "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, "util": { "version": "0.10.4", @@ -11026,6 +11688,11 @@ "object.getownpropertydescriptors": "^2.0.3" } }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", @@ -11048,6 +11715,16 @@ "spdx-expression-parse": "^3.0.0" } }, + "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.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -11102,6 +11779,14 @@ "browser-process-hrtime": "^0.1.2" } }, + "walk": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/walk/-/walk-2.3.9.tgz", + "integrity": "sha1-MbTbZnjyrgHDnqn7hyWpAx5Vins=", + "requires": { + "foreachasync": "^3.0.0" + } + }, "walker": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", @@ -11111,6 +11796,14 @@ "makeerror": "1.0.x" } }, + "warning": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.1.tgz", + "integrity": "sha512-rAVtTNZw+cQPjvGp1ox0XC5Q2IBFyqoqh+QII4J/oguyu83Bax1apbo2eqB8bHRS+fqYUBagys6lqUoVwKSmXQ==", + "requires": { + "loose-envify": "^1.0.0" + } + }, "watch": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/watch/-/watch-0.18.0.tgz", @@ -11606,7 +12299,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -11626,18 +12318,24 @@ "string-width": "^1.0.2 || 2" } }, + "widest-line": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.0.tgz", + "integrity": "sha1-AUKk6KJD+IgsAjOqDgKBqnYVInM=", + "requires": { + "string-width": "^2.1.1" + } + }, "window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "dev": true, "optional": true }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" }, "worker-farm": { "version": "1.6.0", @@ -11690,7 +12388,6 @@ "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", @@ -11707,6 +12404,11 @@ "safe-buffer": "~5.1.0" } }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" + }, "xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", @@ -11728,8 +12430,7 @@ "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, "yargs": { "version": "10.1.2", diff --git a/package.json b/package.json index c7bc104..f9e45f0 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "scripts": { "test": "jest", "dev": "webpack --mode development --watch", - "build": "webpack --mode production" + "build": "webpack --mode production", + "nodemon": "nodemon ./server.js localhost:8080" }, "author": "", "license": "ISC", @@ -17,13 +18,18 @@ ] }, "dependencies": { + "body-parser": "^1.18.3", "classnames": "^2.2.6", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", + "express": "^4.16.3", + "hbs": "^4.0.1", + "nodemon": "^1.18.2", "prop-types": "^15.6.2", "react": "^16.2.0", "react-dom": "^16.2.0", "react-redux": "^5.0.7", + "react-router-dom": "^4.3.1", "redux": "^4.0.0", "redux-thunk": "^2.3.0" }, @@ -40,5 +46,8 @@ "style-loader": "^0.21.0", "webpack": "^4.0.1", "webpack-cli": "^2.0.9" + }, + "engines": { + "node": "8.11.2" } } diff --git a/server.js b/server.js new file mode 100644 index 0000000..82e90db --- /dev/null +++ b/server.js @@ -0,0 +1,24 @@ +const express = require('express'); +const bodyParser = require('body-parser'); +const app = express(); + +app.use(bodyParser.json()); +app.use('/dist', express.static('dist')); +app.set('view engine', 'hbs'); + + +// Render index.hbs template +app.get('*', function (req, res) { + res.render('index'); +}); + +// Server stuff +app.listen(8080, function () { + console.log('Listening on port 8080'); +}); +// Heroku +// const port = process.env.PORT || 8080; +// app.listen(port, function () { +// console.log(`Listening on port number ${port}`); +// }); + diff --git a/src/components/App.js b/src/components/App.js index bc9d39a..7a1f503 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -1,4 +1,6 @@ import React from 'react'; +import { Route, Switch } from 'react-router-dom'; + import Header from './Header'; import OptionsContainer from '../containers/OptionsContainer'; import ScoreContainer from '../containers/ScoreContainer'; @@ -14,12 +16,32 @@ class App extends React.Component { return (
- - - - - - + + { + return
+ + + + + + +
+ } + } /> + { + return
+ + + + + + +
+ }} /> + /> +
+ +
) } diff --git a/src/index.js b/src/index.js index 846662e..321c6bd 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; +import { BrowserRouter, Route } from 'react-router-dom'; import App from './components/App'; import thunkMiddleware from 'redux-thunk'; @@ -13,7 +14,9 @@ const store = createStore(rootReducer, applyMiddleware( ReactDOM.render( - + + + , document.getElementById('root') ); diff --git a/index.html b/views/index.hbs similarity index 100% rename from index.html rename to views/index.hbs From 99a54d6c4a9bb33f52c84533bf5b0848c36c3138 Mon Sep 17 00:00:00 2001 From: Ralph Date: Mon, 16 Jul 2018 09:41:23 +0100 Subject: [PATCH 17/24] Message bug fix --- src/components/Answers.js | 2 +- src/components/Message.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Answers.js b/src/components/Answers.js index 47cdf10..a4aacab 100644 --- a/src/components/Answers.js +++ b/src/components/Answers.js @@ -37,8 +37,8 @@ function Answers({ if (currentQuestion === +totalQuestions) return; } else { e.target.classList.add('animated', 'shake', 'answers__button--wrong-answer'); - scoreUpdate(score - 10); isRightAnswer(false); + scoreUpdate(score - 10); incrementCurrentQuestion(currentQuestion + 1); e.target.setAttribute("disabled", "disabled"); viewMessage(true); diff --git a/src/components/Message.js b/src/components/Message.js index 59b9197..cd5928f 100644 --- a/src/components/Message.js +++ b/src/components/Message.js @@ -14,7 +14,7 @@ function Message({ questionAnswer, score, viewMessage, updateMessage }) { setTimeout(() => { updateMessage(false); - }, 3000); + }, 1500); return (
From c6a6ac3039691064e2ca2c728ad9ab2bd7c97301 Mon Sep 17 00:00:00 2001 From: Ralph Date: Mon, 16 Jul 2018 09:49:23 +0100 Subject: [PATCH 18/24] Added navigation --- src/components/Header.js | 3 +++ src/components/Navigation.js | 14 ++++++++++++++ src/static/styles/navigation.scss | 14 ++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 src/components/Navigation.js create mode 100644 src/static/styles/navigation.scss diff --git a/src/components/Header.js b/src/components/Header.js index bb03c9f..36cc74e 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -1,9 +1,12 @@ import React from 'react'; +import Navigation from './Navigation'; + import '../static/styles/header.scss'; function Header() { return (
+

Quiz

Machine
diff --git a/src/components/Navigation.js b/src/components/Navigation.js new file mode 100644 index 0000000..2c2cf23 --- /dev/null +++ b/src/components/Navigation.js @@ -0,0 +1,14 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; + +import "../static/styles/navigation.scss"; + +function Navigation(props) { + return ( +
+ Quiz + Hall Of Fame +
+ ) +} +export default Navigation; \ No newline at end of file diff --git a/src/static/styles/navigation.scss b/src/static/styles/navigation.scss new file mode 100644 index 0000000..90aea5a --- /dev/null +++ b/src/static/styles/navigation.scss @@ -0,0 +1,14 @@ +.navigation { + display: flex; + justify-content: flex-end; + + .navigation__item { + color: var(--secondary-color); + margin-left: 10px; + text-decoration: none; + + &:hover { + color: #fff; + } + } +} \ No newline at end of file From 8f3812bb2dbf47b67aa350a8132632f5ce5576a7 Mon Sep 17 00:00:00 2001 From: Ralph Date: Mon, 16 Jul 2018 20:17:07 +0100 Subject: [PATCH 19/24] Added hall-of-fame component --- src/components/App.js | 7 +++++++ src/components/HallOfFame.js | 12 ++++++++++++ src/containers/HallOfFameContainer.js | 23 +++++++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 src/components/HallOfFame.js create mode 100644 src/containers/HallOfFameContainer.js diff --git a/src/components/App.js b/src/components/App.js index 7a1f503..6fe7efb 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -8,6 +8,7 @@ import QuestionContainer from '../containers/QuestionContainer'; import AnswersContainer from '../containers/AnswersContainer'; import MessageContainer from '../containers/MessageContainer'; import ButtonSkipQuestionContainer from '../containers/ButtonSkipQuestionContainer'; +import HallOfFameContainer from '../containers/HallOfFameContainer'; import '../static/styles/style.scss'; @@ -39,6 +40,12 @@ class App extends React.Component {
}} /> /> + { + return
+ +
+ }} /> + /> diff --git a/src/components/HallOfFame.js b/src/components/HallOfFame.js new file mode 100644 index 0000000..4950a53 --- /dev/null +++ b/src/components/HallOfFame.js @@ -0,0 +1,12 @@ +import React from 'react'; + +// import '../static/styles/hall-of-fame.scss'; + +function HallOfFame() { + return ( +
+

Hall Of Fame

+
+ ); +} +export default HallOfFame; \ No newline at end of file diff --git a/src/containers/HallOfFameContainer.js b/src/containers/HallOfFameContainer.js new file mode 100644 index 0000000..9801bd2 --- /dev/null +++ b/src/containers/HallOfFameContainer.js @@ -0,0 +1,23 @@ +import { connect } from 'react-redux' +import HallOfFame from '../components/HallOfFame'; +// import { +// fetchQuestion, +// isRightAnswer, +// scoreUpdate, +// currentQuestion +// } from '../actions'; + +export const mapStateToProps = reduxStore => { + return { + }; +}; + +const mapDispatchToProps = dispatch => { + return { + } +}; + +export default connect( + mapStateToProps, + mapDispatchToProps +)(HallOfFame); \ No newline at end of file From 766ca183a946a9c12297b0b921995de327594254 Mon Sep 17 00:00:00 2001 From: Ralph Date: Mon, 16 Jul 2018 20:58:36 +0100 Subject: [PATCH 20/24] Bug fix stoping question count on end game --- src/components/Answers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Answers.js b/src/components/Answers.js index a4aacab..58beeff 100644 --- a/src/components/Answers.js +++ b/src/components/Answers.js @@ -29,20 +29,20 @@ function Answers({ isRightAnswer(true); e.target.classList.add('animated', 'pulse', 'answers__button--correct-answer'); scoreUpdate(score + 10); - incrementCurrentQuestion(currentQuestion + 1); setTimeout(() => { isRightAnswer(false); }, 2000) viewMessage(true); if (currentQuestion === +totalQuestions) return; + incrementCurrentQuestion(currentQuestion + 1); } else { e.target.classList.add('animated', 'shake', 'answers__button--wrong-answer'); isRightAnswer(false); scoreUpdate(score - 10); - incrementCurrentQuestion(currentQuestion + 1); e.target.setAttribute("disabled", "disabled"); viewMessage(true); if (currentQuestion === +totalQuestions) { isRightAnswer(true); return }; + incrementCurrentQuestion(currentQuestion + 1); } } From 36a0a5b63ed5b05710f25773e4977edcfe35c19b Mon Sep 17 00:00:00 2001 From: Ralph Date: Wed, 18 Jul 2018 13:58:14 +0100 Subject: [PATCH 21/24] Added start page --- src/components/Answers.js | 2 +- src/components/App.js | 16 ++++++---------- src/components/Navigation.js | 1 + src/components/Start.js | 9 +++++++++ src/containers/StartContainer.js | 21 +++++++++++++++++++++ src/reducers/currentQuestion.js | 1 + 6 files changed, 39 insertions(+), 11 deletions(-) create mode 100644 src/components/Start.js create mode 100644 src/containers/StartContainer.js diff --git a/src/components/Answers.js b/src/components/Answers.js index 58beeff..55e33e0 100644 --- a/src/components/Answers.js +++ b/src/components/Answers.js @@ -20,7 +20,7 @@ function Answers({ ? [...answers.results[0].incorrect_answers, answers.results[0].correct_answer] : []; - const shuffled_answers = question_answers; //.sort(() => 0.5 - Math.random()); + const shuffled_answers = question_answers.sort(() => 0.5 - Math.random()); function verifyAnswer(e, answer) { e.preventDefault(); diff --git a/src/components/App.js b/src/components/App.js index 6fe7efb..8e0fada 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -2,6 +2,7 @@ import React from 'react'; import { Route, Switch } from 'react-router-dom'; import Header from './Header'; +import StartContainer from '../containers/StartContainer'; import OptionsContainer from '../containers/OptionsContainer'; import ScoreContainer from '../containers/ScoreContainer'; import QuestionContainer from '../containers/QuestionContainer'; @@ -19,16 +20,11 @@ class App extends React.Component {
{ - return
- - - - - - -
- } - } /> + return + }} /> + { + return + }} /> { return
diff --git a/src/components/Navigation.js b/src/components/Navigation.js index 2c2cf23..9ef45ee 100644 --- a/src/components/Navigation.js +++ b/src/components/Navigation.js @@ -6,6 +6,7 @@ import "../static/styles/navigation.scss"; function Navigation(props) { return (
+ Start Quiz Hall Of Fame
diff --git a/src/components/Start.js b/src/components/Start.js new file mode 100644 index 0000000..7fe4752 --- /dev/null +++ b/src/components/Start.js @@ -0,0 +1,9 @@ +import React from 'react'; + +function Start() { + return ( +
Start
+ ) +} + +export default Start; \ No newline at end of file diff --git a/src/containers/StartContainer.js b/src/containers/StartContainer.js new file mode 100644 index 0000000..9d0c403 --- /dev/null +++ b/src/containers/StartContainer.js @@ -0,0 +1,21 @@ +import React from 'react'; +import Start from '../components/Start'; +import { connect } from 'react-redux'; + +// const mapStateToProps = reduxStore => { +// return { + +// } +// } + +// const mapDispatchToProps = reduxStore => { +// return { + +// } +// } + +export default connect( + null, null + // mapStateToProps, + // mapDispatchToProps +)(Start); \ No newline at end of file diff --git a/src/reducers/currentQuestion.js b/src/reducers/currentQuestion.js index 2439be7..6b55d4b 100644 --- a/src/reducers/currentQuestion.js +++ b/src/reducers/currentQuestion.js @@ -3,6 +3,7 @@ function currentQuestion( switch (action.type) { case 'RECEIVE_CURRENT_QUESTION': return action.currentQuestion + default: return state } From 4a45d8f08a9a02d3b0eca52421156288c0f6cc9a Mon Sep 17 00:00:00 2001 From: Ralph Date: Sat, 21 Jul 2018 15:59:40 +0100 Subject: [PATCH 22/24] Refactor Answers --- src/components/Answers.js | 225 ++++++++++++++--------------- src/components/App.js | 2 +- src/components/ButtonAnswer.js | 46 ++++++ src/components/Navigation.js | 2 +- src/components/Options.js | 35 +++-- src/components/Question.js | 2 +- src/components/Start.js | 3 +- src/containers/AnswersContainer.js | 10 +- src/static/styles/options.scss | 20 +-- 9 files changed, 203 insertions(+), 142 deletions(-) create mode 100644 src/components/ButtonAnswer.js diff --git a/src/components/Answers.js b/src/components/Answers.js index 55e33e0..b6aa704 100644 --- a/src/components/Answers.js +++ b/src/components/Answers.js @@ -1,69 +1,130 @@ import React from 'react'; -import cx from 'classnames'; +import { Redirect } from 'react-router-dom'; +import ButtonAnswer from './ButtonAnswer'; import '../static/styles/answers.scss'; -function Answers({ - answers, - isRightAnswer, - score, - scoreUpdate, - requestQuestion, - category, - difficulty, - incrementCurrentQuestion, - currentQuestion, - totalQuestions, - viewMessage -}) { - - const question_answers = answers - ? [...answers.results[0].incorrect_answers, answers.results[0].correct_answer] - : []; - - const shuffled_answers = question_answers.sort(() => 0.5 - Math.random()); - - function verifyAnswer(e, answer) { +class Answers extends React.Component { + + constructor(props) { + super(props); + this.state = { + answers: {}, + shuffled_answers: [], + redirect: false + } + this.verifyAnswer = this.verifyAnswer.bind(this); + this.endOfQuestions = this.endOfQuestions.bind(this); + this.setRedirect = this.setRedirect.bind(this); + this.renderRedirect = this.renderRedirect.bind(this); + } + + // componentDidMount() { + // console.log("this.props", this.props) + // const question_answers = this.state.answers.results + // ? [...this.state.answers.results[0].incorrect_answers, this.state.answers.results[0].correct_answer] + // : []; + + // this.setState({ + // shuffled_answers: question_answers.sort(() => 0.5 - Math.random()) + // }) + + // } + + componentWillReceiveProps(nextProps) { + this.setState({ answers: nextProps.answers }); + const question_answers = nextProps.answers.results + ? [...nextProps.answers.results[0].incorrect_answers, nextProps.answers.results[0].correct_answer] + : []; + + this.setState({ + shuffled_answers: question_answers.sort(() => 0.5 - Math.random()) + }) + } + + verifyAnswer(e, answer) { e.preventDefault(); - if (answer === answers.results[0].correct_answer) { - isRightAnswer(true); - e.target.classList.add('animated', 'pulse', 'answers__button--correct-answer'); - scoreUpdate(score + 10); + if (answer === this.state.answers.results[0].correct_answer) { + this.props.isRightAnswer(true); + // e.target.classList.add('animated', 'pulse', 'answers__button--correct-answer'); + this.props.scoreUpdate(this.props.score + 10); + this.props.viewMessage(true); setTimeout(() => { - isRightAnswer(false); - }, 2000) - viewMessage(true); - if (currentQuestion === +totalQuestions) return; - incrementCurrentQuestion(currentQuestion + 1); + this.props.isRightAnswer(false); + }, 3000) + this.props.requestQuestion(this.props.category, this.props.difficulty); + if (this.props.currentQuestion === +this.props.totalQuestions) return; + this.props.incrementCurrentQuestion(this.props.currentQuestion + 1); } else { - e.target.classList.add('animated', 'shake', 'answers__button--wrong-answer'); - isRightAnswer(false); - scoreUpdate(score - 10); - e.target.setAttribute("disabled", "disabled"); - viewMessage(true); - if (currentQuestion === +totalQuestions) { isRightAnswer(true); return }; - incrementCurrentQuestion(currentQuestion + 1); + // e.target.classList.add('animated', 'shake', 'answers__button--wrong-answer'); + this.props.isRightAnswer(false); + this.props.scoreUpdate(this.props.score - 10); + + + // e.target.setAttribute("disabled", "disabled"); + this.props.viewMessage(true); + + setTimeout(() => { + this.props.requestQuestion(this.props.category, this.props.difficulty); + }, 3000) + if (this.props.currentQuestion === +this.props.totalQuestions) { this.props.isRightAnswer(true); return }; + this.props.incrementCurrentQuestion(this.props.currentQuestion + 1); } } - function endOfQuestions() { + endOfQuestions() { // console.log("currentQuestion", currentQuestion); // console.log("totalQuestions", totalQuestions); - if (currentQuestion === +totalQuestions) { + if (this.props.currentQuestion === +this.props.totalQuestions) { // Open end game message console.log('game ends'); + + setTimeout(() => { + this.setRedirect(); + }, 2000) } else { setTimeout(() => { - requestQuestion(category, difficulty); - isRightAnswer(false); + // requestQuestion(category, difficulty); + this.props.isRightAnswer(false); }, 2000) } } - return ( -
- {shuffled_answers.map(answer => { - return - })} -
- ) -} - -export default Answers; - - -// import React from 'react'; -// import cx from 'classnames'; -// import '../static/styles/answers.scss'; - -// class Answers extends React.Component { -// //({ answers, isRightAnswer, score, scoreUpdate }) -// constructor(props) { -// super(props); -// this.state = { -// question_answers: [] - -// // shuffled_answers: question_answers //.sort(() => 0.5 - Math.random()); -// } -// } - -// componentDidMount() { -// console.log("this.props.answers", this.props) -// this.setState( -// { -// question_answers: this.props.answers -// ? [...this.props.answers.results[0].incorrect_answers, this.props.answers.results[0].correct_answer] -// : ['sssss'], -// } -// ) -// } - -// verifyAnswer(e, answer) { -// e.preventDefault(); -// if (answer === this.props.answers.results[0].correct_answer) { -// console.log("Right!"); -// this.props.isRightAnswer(true); -// this.props.scoreUpdate(score + 10); -// e.target.classList.add('correct-answer'); -// } else { -// console.log("Wrong!"); -// this.props.isRightAnswer(false); -// this.props.scoreUpdate(score - 10); -// e.target.classList.add('disabled'); -// } -// } - -// render() { -// console.log("this.state.question_answers", this.state.question_answers) -// return ( -//
-// {this.state.question_answers.map(answer => { -// return -// })} -//
-// ) -// } -// } - -// export default Answers; + */ \ No newline at end of file diff --git a/src/components/App.js b/src/components/App.js index 8e0fada..f34eb42 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -27,7 +27,7 @@ class App extends React.Component { }} /> { return
- + {/* */} diff --git a/src/components/ButtonAnswer.js b/src/components/ButtonAnswer.js new file mode 100644 index 0000000..dd55e88 --- /dev/null +++ b/src/components/ButtonAnswer.js @@ -0,0 +1,46 @@ +import React from 'react'; +import cx from 'classnames'; + +class ButtonAnswer extends React.Component { + constructor(props) { + super(props); + + this.state = { + isClicked: false + } + + this.onClickHandler = this.onClickHandler.bind(this); + } + + onClickHandler() { + this.setState({ + isClicked: true + }) + } + + + render() { + console.log("this.props.isRight", this.props.isRight); + return ( + + ) + } +} + +export default ButtonAnswer; \ No newline at end of file diff --git a/src/components/Navigation.js b/src/components/Navigation.js index 9ef45ee..e381227 100644 --- a/src/components/Navigation.js +++ b/src/components/Navigation.js @@ -7,7 +7,7 @@ function Navigation(props) { return (
Start - Quiz + {/* Quiz */} Hall Of Fame
) diff --git a/src/components/Options.js b/src/components/Options.js index 7c2cc9e..5310af1 100644 --- a/src/components/Options.js +++ b/src/components/Options.js @@ -1,5 +1,6 @@ import React from 'react'; import cx from 'classnames'; +import { Redirect } from 'react-router-dom'; import "../static/styles/options.scss"; class Options extends React.Component { @@ -9,19 +10,20 @@ class Options extends React.Component { category: '', categoryName: '', difficulty: '', - optionsOpen: false, + + redirect: false, + // optionsOpen: false, questionsAmount: 10 } this.updateCategory = this.updateCategory.bind(this); this.updateDifficulty = this.updateDifficulty.bind(this); - this.toggleOptions = this.toggleOptions.bind(this); + this.setRedirect = this.setRedirect.bind(this); + this.renderRedirect = this.renderRedirect.bind(this); + // this.toggleOptions = this.toggleOptions.bind(this); this.updateCategory = this.updateCategory.bind(this); - // this.updateReduxCategory = this.updateCategory.bind(this); this.updateDifficulty = this.updateDifficulty.bind(this); - // this.updateReduxDifficulty = this.updateDifficulty.bind(this); this.updateQuestionsAmount = this.updateQuestionsAmount.bind(this); - // this.updateReduxQuestionsAmount = this.updateReduxQuestionsAmount.bind(this); } updateCategory(e) { @@ -51,6 +53,7 @@ class Options extends React.Component { updateReduxDifficulty() { this.props.optionsDifficulty(this.state.difficulty); + this.setRedirect(); } updateReduxQuestionsAmount() { @@ -58,10 +61,22 @@ class Options extends React.Component { this.props.updateReduxQuestionsAmount(this.state.questionsAmount); } - toggleOptions() { + // toggleOptions() { + // this.setState({ + // optionsOpen: !this.state.optionsOpen + // }) + // } + + setRedirect() { this.setState({ - optionsOpen: !this.state.optionsOpen - }) + redirect: true + }); + } + + renderRedirect() { + if (this.state.redirect) { + return ; + } } render() { @@ -70,6 +85,7 @@ class Options extends React.Component { }); return (
+ {this.renderRedirect()}
@@ -154,12 +170,11 @@ class Options extends React.Component { this.props.requestQuestionsUpdate(this.state.category, this.state.difficulty, 1); this.props.currentQuestion(1); this.props.scoreUpdate(0); - this.toggleOptions(); this.updateReduxCategory(e); this.updateReduxDifficulty(e); this.updateReduxQuestionsAmount(e); }}> - Update + Go!
diff --git a/src/components/Question.js b/src/components/Question.js index 3ec08be..25475e6 100644 --- a/src/components/Question.js +++ b/src/components/Question.js @@ -7,7 +7,7 @@ class Question extends React.Component { } componentDidMount() { - this.props.requestQuestion(); + // this.props.requestQuestion(); } render() { diff --git a/src/components/Start.js b/src/components/Start.js index 7fe4752..be2c611 100644 --- a/src/components/Start.js +++ b/src/components/Start.js @@ -1,8 +1,9 @@ import React from 'react'; +import OptionsContainer from '../containers/OptionsContainer'; function Start() { return ( -
Start
+ ) } diff --git a/src/containers/AnswersContainer.js b/src/containers/AnswersContainer.js index 78bc6c6..5875315 100644 --- a/src/containers/AnswersContainer.js +++ b/src/containers/AnswersContainer.js @@ -1,8 +1,16 @@ import { connect } from 'react-redux' import Answers from '../components/Answers'; -import { viewMessage, isRightAnswer, scoreUpdate, fetchQuestion, currentQuestion } from '../actions'; +import { + viewMessage, + isRightAnswer, + scoreUpdate, + fetchQuestion, + currentQuestion +} + from '../actions'; export const mapStateToProps = reduxStore => { + console.log("reduxStore", reduxStore) return { answers: reduxStore.quizQuestion, score: reduxStore.score, diff --git a/src/static/styles/options.scss b/src/static/styles/options.scss index 2218e1d..9c79aac 100644 --- a/src/static/styles/options.scss +++ b/src/static/styles/options.scss @@ -1,11 +1,11 @@ .options { - .options__list { - display: none; + // .options__list { + // display: none; - &.visible { - display: block; - } - } + // &.visible { + // display: block; + // } + // } .options__toggle { display: flex; @@ -19,10 +19,10 @@ margin-bottom: 10px; color: #fff; - &:hover { - cursor: pointer; - opacity: .8; - } + // &:hover { + // cursor: pointer; + // opacity: .8; + // } } } From 6861dc8c4aa9fecd19ba9798591a63aa1619a080 Mon Sep 17 00:00:00 2001 From: Ralph Date: Sat, 21 Jul 2018 20:47:04 +0100 Subject: [PATCH 23/24] Added random questions --- src/actions/index.js | 7 +++++++ src/components/Answers.js | 28 +++++++++++++++------------- src/components/ButtonAnswer.js | 1 - src/containers/AnswersContainer.js | 6 ++++-- src/reducers/index.js | 4 +++- src/reducers/randomArray.js | 11 +++++++++++ 6 files changed, 40 insertions(+), 17 deletions(-) create mode 100644 src/reducers/randomArray.js diff --git a/src/actions/index.js b/src/actions/index.js index b5cad65..7b7fa6e 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -62,6 +62,13 @@ export function viewMessage(viewMessage) { } } +export function generateArray(array) { + return { + type: 'ARRAY_RECEIVE', + randomArray: array + } +} + export function fetchQuestion(category = '', difficulty = '', amount = 1) { return function (dispatch) { fetch(`https://opentdb.com/api.php?amount=${amount}&type=multiple&category=${category}&difficulty=${difficulty}&encode=url3986`) diff --git a/src/components/Answers.js b/src/components/Answers.js index b6aa704..5b54309 100644 --- a/src/components/Answers.js +++ b/src/components/Answers.js @@ -18,17 +18,8 @@ class Answers extends React.Component { this.renderRedirect = this.renderRedirect.bind(this); } - // componentDidMount() { - // console.log("this.props", this.props) - // const question_answers = this.state.answers.results - // ? [...this.state.answers.results[0].incorrect_answers, this.state.answers.results[0].correct_answer] - // : []; - - // this.setState({ - // shuffled_answers: question_answers.sort(() => 0.5 - Math.random()) - // }) - - // } + componentDidMount() { + } componentWillReceiveProps(nextProps) { this.setState({ answers: nextProps.answers }); @@ -36,8 +27,18 @@ class Answers extends React.Component { ? [...nextProps.answers.results[0].incorrect_answers, nextProps.answers.results[0].correct_answer] : []; + //If they are new answers generate random array + if (nextProps.answers !== this.state.answers) { + this.props.generateArray(this.props.randomArray.sort(() => 0.5 - Math.random())); + } + + // Generate array with suffled questions + const suffled = []; + this.props.randomArray.map(position => { + suffled.push(question_answers[position]); + }) this.setState({ - shuffled_answers: question_answers.sort(() => 0.5 - Math.random()) + shuffled_answers: suffled }) } @@ -66,7 +67,7 @@ class Answers extends React.Component { setTimeout(() => { this.props.requestQuestion(this.props.category, this.props.difficulty); - }, 3000) + }, 1000) if (this.props.currentQuestion === +this.props.totalQuestions) { this.props.isRightAnswer(true); return }; this.props.incrementCurrentQuestion(this.props.currentQuestion + 1); } @@ -113,6 +114,7 @@ class Answers extends React.Component { isRight={answer === this.state.answers.results[0].correct_answer} verifyAnswer={this.verifyAnswer} endOfQuestions={this.endOfQuestions} + /> }) } diff --git a/src/components/ButtonAnswer.js b/src/components/ButtonAnswer.js index dd55e88..cbd4c79 100644 --- a/src/components/ButtonAnswer.js +++ b/src/components/ButtonAnswer.js @@ -20,7 +20,6 @@ class ButtonAnswer extends React.Component { render() { - console.log("this.props.isRight", this.props.isRight); return ( */ \ No newline at end of file +export default Answers; \ No newline at end of file diff --git a/src/components/App.js b/src/components/App.js index f34eb42..83a8b48 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -9,7 +9,7 @@ import QuestionContainer from '../containers/QuestionContainer'; import AnswersContainer from '../containers/AnswersContainer'; import MessageContainer from '../containers/MessageContainer'; import ButtonSkipQuestionContainer from '../containers/ButtonSkipQuestionContainer'; -import HallOfFameContainer from '../containers/HallOfFameContainer'; +import LeaderboardContainer from '../containers/LeaderboardContainer'; import '../static/styles/style.scss'; @@ -36,9 +36,9 @@ class App extends React.Component {
}} /> /> - { + { return
- +
}} /> /> diff --git a/src/components/HallOfFame.js b/src/components/HallOfFame.js deleted file mode 100644 index 4950a53..0000000 --- a/src/components/HallOfFame.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react'; - -// import '../static/styles/hall-of-fame.scss'; - -function HallOfFame() { - return ( -
-

Hall Of Fame

-
- ); -} -export default HallOfFame; \ No newline at end of file diff --git a/src/components/Leaderboard.js b/src/components/Leaderboard.js new file mode 100644 index 0000000..8535440 --- /dev/null +++ b/src/components/Leaderboard.js @@ -0,0 +1,103 @@ +import React from 'react'; +import cx from 'classnames'; + +import '../static/styles/leaderboard.scss'; + +class Leaderboard extends React.Component { + constructor(props) { + super(props) + this.state = { + id: [Object.keys(this.props.leaderboard).length], + playerName: '', + sorted: [], + leaderboardNameAdded: false + } + this.onSubmitHandler = this.onSubmitHandler.bind(this); + this.onChangeHandler = this.onChangeHandler.bind(this); + } + + componentWillMount() { + const sorted = Object.keys(this.props.leaderboard).sort((a, b) => { + return this.props.leaderboard[b].points - this.props.leaderboard[a].points + }); + + this.setState({ + sorted: sorted + }) + } + + onSubmitHandler(e) { + e.preventDefault(); + this.setState({ + [+this.state.id + 1]: { + player: this.state.playerName, + points: this.props.score + } + }); + + const leaders = Object.assign({}, this.props.leaderboard, { + [+this.state.id + 1]: { + player: this.state.playerName, + points: this.props.score + } + } + ) + this.props.leaderboardList(leaders); + + const sorted = Object.keys(leaders).sort((a, b) => { + return leaders[b].points - leaders[a].points + }); + + this.setState({ + sorted: sorted, + leaderboardNameAdded: true + }) + } + + onChangeHandler(e) { + this.setState({ + playerName: e.target.value + }); + } + + render() { + return ( +
+

Leaderboard

+
this.onSubmitHandler(e)} + className={cx('leaderboard__form', { + "leaderboard__form--name-added": this.state.leaderboardNameAdded + })}> +
+ Add your name to the list + +
+ this.onChangeHandler(e)} type="text" placeholder="Name" /> + +
+
+
+ +
+
+
+
 
+
Player
+
Points
+
+ { + Object.keys(this.props.leaderboard).map((rank, index) => { + return
+
{index + 1}
+
{this.props.leaderboard[this.state.sorted[index]].player}
+
{this.props.leaderboard[this.state.sorted[index]].points}
+
+ }) + } +
+
+
+ ); + } +} +export default Leaderboard; \ No newline at end of file diff --git a/src/components/Message.js b/src/components/Message.js index cd5928f..9a7fe9b 100644 --- a/src/components/Message.js +++ b/src/components/Message.js @@ -7,6 +7,7 @@ function Message({ questionAnswer, score, viewMessage, updateMessage }) { visible: viewMessage, animated: questionAnswer, fadeIn: questionAnswer, + correct: questionAnswer }); const CoverClasses = cx('cover ', { visible: viewMessage @@ -19,7 +20,7 @@ function Message({ questionAnswer, score, viewMessage, updateMessage }) { return (
- {questionAnswer ? "+ 10 points!" : "- 10 points!"} + {questionAnswer ? "+ 10!" : "- 10!"}
diff --git a/src/components/Navigation.js b/src/components/Navigation.js index e381227..8beb5d0 100644 --- a/src/components/Navigation.js +++ b/src/components/Navigation.js @@ -8,7 +8,7 @@ function Navigation(props) {
Start {/* Quiz */} - Hall Of Fame + Leaderboard
) } diff --git a/src/containers/HallOfFameContainer.js b/src/containers/HallOfFameContainer.js deleted file mode 100644 index 9801bd2..0000000 --- a/src/containers/HallOfFameContainer.js +++ /dev/null @@ -1,23 +0,0 @@ -import { connect } from 'react-redux' -import HallOfFame from '../components/HallOfFame'; -// import { -// fetchQuestion, -// isRightAnswer, -// scoreUpdate, -// currentQuestion -// } from '../actions'; - -export const mapStateToProps = reduxStore => { - return { - }; -}; - -const mapDispatchToProps = dispatch => { - return { - } -}; - -export default connect( - mapStateToProps, - mapDispatchToProps -)(HallOfFame); \ No newline at end of file diff --git a/src/containers/LeaderboardContainer.js b/src/containers/LeaderboardContainer.js new file mode 100644 index 0000000..5bdd786 --- /dev/null +++ b/src/containers/LeaderboardContainer.js @@ -0,0 +1,23 @@ +import { connect } from 'react-redux' +import Leaderboard from '../components/Leaderboard'; +import { + leaderboardList +} from '../actions'; + +export const mapStateToProps = reduxStore => { + return { + score: reduxStore.score, + leaderboard: reduxStore.leaderboard + }; +}; + +const mapDispatchToProps = dispatch => { + return { + leaderboardList: data => dispatch(leaderboardList(data)) + } +}; + +export default connect( + mapStateToProps, + mapDispatchToProps +)(Leaderboard); \ No newline at end of file diff --git a/src/reducers/index.js b/src/reducers/index.js index 0f638a6..a350ccd 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -9,6 +9,7 @@ import currentQuestion from './currentQuestion'; import updateReduxQuestionsAmount from './updateReduxQuestionsAmount'; import viewMessage from './viewMessage'; import randomArray from './randomArray'; +import leaderboard from './leaderboard'; export default combineReducers({ quizQuestion, @@ -20,5 +21,6 @@ export default combineReducers({ currentQuestion, updateReduxQuestionsAmount, viewMessage, - randomArray + randomArray, + leaderboard }); diff --git a/src/reducers/leaderboard.js b/src/reducers/leaderboard.js new file mode 100644 index 0000000..0aff26c --- /dev/null +++ b/src/reducers/leaderboard.js @@ -0,0 +1,31 @@ +function leaderboard(state = { + 1: { + player: "Bear", + points: "60" + }, + 2: { + player: "Wolf", + points: "20" + }, + 3: { + player: "Ant", + points: "30" + }, + 4: { + player: "Bob", + points: "300" + }, + 5: { + player: "Core", + points: "0" + } +}, action) { + switch (action.type) { + case 'RECEIVE_LEADERBOARD': + return action.leaderboard + default: + return state + } +} + +export default leaderboard; \ No newline at end of file diff --git a/src/static/styles/leaderboard.scss b/src/static/styles/leaderboard.scss new file mode 100644 index 0000000..8262098 --- /dev/null +++ b/src/static/styles/leaderboard.scss @@ -0,0 +1,67 @@ +.leaderboard { + padding-bottom: 50px; + + .leaderboard__list{ + display: table; + width: 100%; + + .leaderboard__list--row { + display: table-row; + } + + .leaderboard__list--cell, .leaderboard__list--head { + border-bottom: 1px solid #fff; + color: #fff; + display: table-cell; + padding: 3px 10px; + } + .leaderboard__list--heading { + background-color: #EEE; + display: table-header-group; + font-weight: bold; + } + .leaderboard__list--body { + display: table-row-group; + } + } + + + .leaderboard__form { + display: flex; + flex-direction: column; + padding: 0px 0 40px; + + .leaderboard__form--wrapper { + border: 1px solid #fff; + } + + &.leaderboard__form--name-added { + display: none; + } + + .leaderboard__form-input--box { + display: flex; + margin-top: 20px; + } + + .leaderboard__form-input { + flex: 1; + padding: 8px; + border: none; + background-color: #fff; + box-sizing: border-box; + } + .leaderboard__form-button { + padding: 8px; + border: none; + background-color: var(--tertiary-color); + width: 100px; + color: #fff; + + &:hover { + cursor: pointer; + opacity: .8; + } + } + } +} diff --git a/src/static/styles/message.scss b/src/static/styles/message.scss index acb7d0c..7f5b801 100644 --- a/src/static/styles/message.scss +++ b/src/static/styles/message.scss @@ -1,19 +1,35 @@ .message { - position: absolute; - top: 50%; - left: 50%; + position: fixed; + top: 50px; + right: 30px; color: #fff; - font-size: 36px; - transform: rotate(-4deg) translate(-50%, -60%); + font-size: 19px; + transform: rotate(-4deg); font-family: 'Bitter', serif; z-index: 2; - - background-color: #fcaa02; - width: 150px; - height: 150px; - border-radius: 10px; + width: 50px; + height: 50px; + border-radius: 5px; z-index: 9999; display: none; + + background-color: var(--wrong-answer-color); + &:before { + background-color: var(--wrong-answer-color); + } + &:after { + background-color: var(--wrong-answer-color); + } + + &.correct { + background-color: var(--correct-answer-color); + &:before { + background-color: var(--correct-answer-color); + } + &:after { + background-color: var(--correct-answer-color); + } + } &.visible { display: block; @@ -21,10 +37,9 @@ &:after { content: ""; - background-color: #fcaa02; - width: 150px; - height: 150px; - border-radius: 10px; + width: 50px; + height: 50px; + border-radius: 5px; transform: rotate(30deg); position: absolute; top: 0; @@ -33,10 +48,9 @@ &:before { content: ""; - background-color: #fcaa02; - width: 150px; - height: 150px; - border-radius: 10px; + width: 50px; + height: 50px; + border-radius: 5px; transform: rotate(60deg); position: absolute; top: 0; @@ -45,8 +59,8 @@ .message__text { z-index: 99999; - position: absolute; - top: 20%; + position: fixed; + top: 24%; left: 4%; text-align: center; }