diff --git a/.gitignore b/.gitignore index ea3e487..670085d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,23 @@ build static +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +package-lock.json node_modules -dist + *.egg-info *.pyc *.pyo *~ .* !.git* +!.babelrc +!.eslintrc +!.nvmrc /*env docs/_build *.ipynb diff --git a/README.md b/README.md index 76bfd0f..bb2a4b6 100644 --- a/README.md +++ b/README.md @@ -28,36 +28,53 @@ Running Votr sudo apt install virtualenv -2. Install node.js and npm. (Some Linux distributions bundle them together in - one package.) Check the version: npm 1 and 2 are too old. npm 3 and 4 are - probably OK. npm 5+ is ideal, but most Linux distributions don't have it yet - (including current Ubuntu and Debian). In that case, you can either: - - * Install npm 3 despite its age and hope for the best. E.g. on Ubuntu: - `sudo apt install nodejs-legacy npm`. - * Use the unofficial up to date repositories from - https://nodejs.org/en/download/package-manager/, and install `nodejs` - (not `nodejs-legacy` and `npm`). - -3. Create a virtualenv directory. A virtualenv is an isolated environment that +2. Create a virtualenv directory. A virtualenv is an isolated environment that contains Python libraries, so that you don't have to install them system-wide, and each project can use different versions without conflicts. virtualenv -p python3 venv -4. Activate the virtualenv. (Basically, this just adds `venv/bin` to your +3. Activate the virtualenv. (Basically, this just adds `venv/bin` to your current shell's `$PATH`. Instead, you could just use `venv/bin/python` instead of `python`, `venv/bin/pip` instead of `pip`, etc.) source venv/bin/activate -5. Install the latest version of `pip` (earlier versions don't support wheels), +4. Install the latest version of `pip` (earlier versions don't support wheels), and then use it to install Python dependencies. pip install -U pip pip install -r requirements.txt -6. Start Votr. Remember to activate the virtualenv first if you haven't done it +5. Gather/build your CSS files: + + # copy pre-built CSS files to votrfront/static/ + ./votrfront/buildcss.sh setup + # build the custom CSS + ./votrfront/buildcss.sh + # build the bootstrap custom base CSS - not needed in 99.99% cases + ./votrfront/buildcss.sh bootstrap + +6. Install Node.js and npm/yarn. You can do so via + [NVM](https://github.com/creationix/nvm). Follow instructions on the NVM + website. After installing NVM, you may need to restart your + terminal / source .bashrc . Afterwards, run: + + cd votrfront/js/ + nvm use + npm i -g yarn + yarn + cd ../.. + +7. Start the Javascript bundler (you will need to have this open in another + terminal): + + cd votrfront/js + yarn dev + # for production build, do + yarn build + +8. Start Votr. Remember to activate the virtualenv first if you haven't done it yet in this terminal. ./console.py serve --debug @@ -79,6 +96,7 @@ Some documentation is on the wiki: https://github.com/fmfi-svt/votr/wiki Some documentation is in docstrings in the source code and rendered with Sphinx: http://svt.fmph.uniba.sk/~tomi/votrdoc/ + Building documentation: pip install sphinx sphinx-rtd-theme diff --git a/votrfront/buildcss.sh b/votrfront/buildcss.sh new file mode 100755 index 0000000..c607995 --- /dev/null +++ b/votrfront/buildcss.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +set -e + +if [ "${1:0:6}" == "--env=" ]; then + source "${1:6}/bin/activate" + shift +fi + +cd "$(dirname "$0")" + +! [ -w "$HOME" ] && echo "HOME is not writable" && exit 1 + +mkdir -p static + +if [ "$1" == "build" ] || [ "$1" == "" ]; then + + sassc -s compressed css/src/main.scss css/dist/votr.css + cp css/dist/votr.css static/votr.css + +elif [ "$1" == "bootstrap" ]; then + + if ! [ -d node_modules/bootstrap-sass ]; then + npm install bootstrap-sass@^3.3 + fi + bs=node_modules/bootstrap-sass/assets + + sed -i " + # Don't use pointer cursor on buttons. + # http://lists.w3.org/Archives/Public/public-css-testsuite/2010Jul/0024.html + s@cursor: pointer; // 3@@ + # Don't inherit color and font on inputs and selects. + s@color: inherit; // 1@@ + s@font: inherit; // 2@@ + " $bs/stylesheets/bootstrap/_normalize.scss + + compressed='-s compressed' + sassc $compressed -I $bs/stylesheets css/src/_votr-bootstrap.scss css/dist/bootstrap.custom.css + cp css/dist/bootstrap.custom.css static/bootstrap.custom.css + +elif [ "$1" == "setup" ]; then + + cp css/dist/bootstrap.custom.css static/bootstrap.custom.css + cp css/dist/votr.css static/votr.css + +elif [ "$1" == "clean" ]; then + + rm -rf node_modules static + +else + echo "usage: $0 [--env=path/to/venv] [build|clean]" + exit 1 +fi diff --git a/votrfront/buildstatic.sh b/votrfront/buildstatic.sh deleted file mode 100755 index b85f5ee..0000000 --- a/votrfront/buildstatic.sh +++ /dev/null @@ -1,101 +0,0 @@ -#!/bin/bash - -set -e - -if [ "${1:0:6}" == "--env=" ]; then - source "${1:6}/bin/activate" - shift -fi - -cd "$(dirname "$0")" - -! [ -w "$HOME" ] && echo "HOME is not writable" && exit 1 - -if [ "$1" == "build" ] || [ "$1" == "" ]; then - - mkdir -p static/libs/ static/cache/ - rm -f static/ok - - if ! [ -f static/libs/jquery.js ]; then - npm install jquery@^1 - cp -p node_modules/jquery/dist/*.* static/libs/ - fi - - if ! [ -f static/libs/lodash.js ]; then - version=$(npm view lodash versions | cut -d\' -f2 | grep '^3\.' | tail -n1) - wget https://raw.githubusercontent.com/lodash/lodash/$version/lodash.js -O static/libs/lodash.js - wget https://raw.githubusercontent.com/lodash/lodash/$version/lodash.min.js -O static/libs/lodash.min.js - fi - - if ! [ -f static/libs/react.js ]; then - npm install react@^0.14 - cp -p node_modules/react/dist/*.* static/libs/ - fi - - if ! [ -f static/libs/react-dom.js ]; then - npm install react-dom@^0.14 - cp -p node_modules/react-dom/dist/*.* static/libs/ - fi - - if ! [ -f static/libs/FileSaver.min.js ]; then - npm install file-saver@^1.3.3 - cp node_modules/file-saver/FileSaver.min.js static/libs/ - fi - - if ! [ -f node_modules/.bin/webpack ]; then - npm install node-libs-browser@^0.5 # from peerDependencies of webpack - npm install babel-core@^5 # from peerDependencies of babel-loader - npm install webpack@^1.10 - npm install babel-loader@^5 - fi - - if ! [ -d node_modules/bootstrap-sass ]; then - npm install bootstrap-sass@^3.3 - fi - bs=node_modules/bootstrap-sass/assets - if ! [ -f static/libs/modal.js ]; then - cp $bs/javascripts/bootstrap/*.js static/libs/ - fi - - if ! [ -f static/spinner.svg ]; then - wget https://raw.githubusercontent.com/kvakes/spinner.svg/master/spinner2.svg -O static/spinner.svg - fi - if ! [ -f static/_spinner.scss ]; then - node -e 'console.log("$spinner: url(data:image/svg+xml;base64," + require("fs").readFileSync("static/spinner.svg", "base64") + ");")' > static/_spinner.scss - fi - - sed -i " - # Don't use pointer cursor on buttons. - # http://lists.w3.org/Archives/Public/public-css-testsuite/2010Jul/0024.html - s@cursor: pointer; // 3@@ - # Don't inherit color and font on inputs and selects. - s@color: inherit; // 1@@ - s@font: inherit; // 2@@ - " $bs/stylesheets/bootstrap/_normalize.scss - - compressed='-s compressed' - sassc $compressed -I $bs/stylesheets -I static css/main.scss static/style.css - - if ! [ -f static/webpacktime ] || [ "$(find js/ webpack.config.js -newer static/webpacktime)" ]; then - touch static/webpacktime - rm -f static/votr.min.js.*.map - ./node_modules/.bin/webpack - else - echo "webpack output is up to date." - fi - - libs='prologue.js libs/jquery.min.js libs/react.min.js libs/react-dom.min.js libs/lodash.min.js libs/transition.js libs/modal.js libs/FileSaver.min.js' - dev=(static/dev/*) - echo ${libs//.min} "${dev[@]//"static/"}" votr.dev.js > static/jsdeps-dev - echo $libs votr.min.js > static/jsdeps-prod - - touch static/ok - -elif [ "$1" == "clean" ]; then - - rm -rf node_modules static - -else - echo "usage: $0 [--env=path/to/venv] [build|clean]" - exit 1 -fi diff --git a/votrfront/css/dist/bootstrap.custom.css b/votrfront/css/dist/bootstrap.custom.css new file mode 100644 index 0000000..90d12d4 --- /dev/null +++ b/votrfront/css/dist/bootstrap.custom.css @@ -0,0 +1 @@ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:transparent}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:1.42857;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#B3231B;text-decoration:none}a:hover,a:focus{color:#711611;text-decoration:underline}a:focus{outline:thin dotted}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all 0.2s ease-in-out;-o-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:18px;margin-bottom:18px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role="button"]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h1 .small,h2 small,h2 .small,h3 small,h3 .small,h4 small,h4 .small,h5 small,h5 .small,h6 small,h6 .small,.h1 small,.h1 .small,.h2 small,.h2 .small,.h3 small,.h3 .small,.h4 small,.h4 .small,.h5 small,.h5 .small,.h6 small,.h6 .small{font-weight:normal;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:18px;margin-bottom:9px}h1 small,h1 .small,.h1 small,.h1 .small,h2 small,h2 .small,.h2 small,.h2 .small,h3 small,h3 .small,.h3 small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:9px;margin-bottom:9px}h4 small,h4 .small,.h4 small,.h4 .small,h5 small,h5 .small,.h5 small,.h5 .small,h6 small,h6 .small,.h6 small,.h6 .small{font-size:75%}h1,.h1{font-size:33px}h2,.h2{font-size:27px}h3,.h3{font-size:23px}h4,.h4{font-size:18px}h5,.h5{font-size:13px}h6,.h6{font-size:12px}p{margin:0 0 9px}.lead{margin-bottom:18px;font-size:14px;font-weight:300;line-height:1.4}@media (min-width: 768px){.lead{font-size:19.5px}}small,.small{font-size:92%}mark,.mark{background-color:#fcf8e3;padding:.2em}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase,.initialism{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#B3231B}a.text-primary:hover,a.text-primary:focus{color:#871a14}.text-success{color:#3c763d}a.text-success:hover,a.text-success:focus{color:#2b542c}.text-info{color:#31708f}a.text-info:hover,a.text-info:focus{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover,a.text-warning:focus{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover,a.text-danger:focus{color:#843534}.bg-primary{color:#fff}.bg-primary{background-color:#B3231B}a.bg-primary:hover,a.bg-primary:focus{background-color:#871a14}.bg-success{background-color:#dff0d8}a.bg-success:hover,a.bg-success:focus{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover,a.bg-info:focus{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover,a.bg-warning:focus{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover,a.bg-danger:focus{background-color:#e4b9b9}.page-header{padding-bottom:8px;margin:36px 0 18px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:9px}ul ul,ul ol,ol ul,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:18px}dt,dd{line-height:1.42857}dt{font-weight:bold}dd{margin-left:0}.dl-horizontal dd:before,.dl-horizontal dd:after{content:" ";display:table}.dl-horizontal dd:after{clear:both}@media (min-width: 768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%}blockquote{padding:9px 18px;margin:0 0 18px;font-size:16.25px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse footer:before,.blockquote-reverse small:before,.blockquote-reverse .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,.blockquote-reverse small:after,.blockquote-reverse .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:18px;font-style:normal;line-height:1.42857}code,kbd,pre,samp{font-family:9pt monospace}code{padding:2px 4px;font-size:90%;color:#333;background-color:#F5F5F5;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)}kbd kbd{padding:0;font-size:100%;font-weight:bold;box-shadow:none}pre{display:block;padding:8.5px;margin:0 0 9px;font-size:12px;line-height:1.42857;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.container:before,.container:after{content:" ";display:table}.container:after{clear:both}@media (min-width: 768px){.container{width:750px}}@media (min-width: 992px){.container{width:970px}}@media (min-width: 1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.container-fluid:before,.container-fluid:after{content:" ";display:table}.container-fluid:after{clear:both}.row{margin-left:-15px;margin-right:-15px}.row:before,.row:after{content:" ";display:table}.row:after{clear:both}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-1{width:8.33333%}.col-xs-2{width:16.66667%}.col-xs-3{width:25%}.col-xs-4{width:33.33333%}.col-xs-5{width:41.66667%}.col-xs-6{width:50%}.col-xs-7{width:58.33333%}.col-xs-8{width:66.66667%}.col-xs-9{width:75%}.col-xs-10{width:83.33333%}.col-xs-11{width:91.66667%}.col-xs-12{width:100%}.col-xs-pull-0{right:auto}.col-xs-pull-1{right:8.33333%}.col-xs-pull-2{right:16.66667%}.col-xs-pull-3{right:25%}.col-xs-pull-4{right:33.33333%}.col-xs-pull-5{right:41.66667%}.col-xs-pull-6{right:50%}.col-xs-pull-7{right:58.33333%}.col-xs-pull-8{right:66.66667%}.col-xs-pull-9{right:75%}.col-xs-pull-10{right:83.33333%}.col-xs-pull-11{right:91.66667%}.col-xs-pull-12{right:100%}.col-xs-push-0{left:auto}.col-xs-push-1{left:8.33333%}.col-xs-push-2{left:16.66667%}.col-xs-push-3{left:25%}.col-xs-push-4{left:33.33333%}.col-xs-push-5{left:41.66667%}.col-xs-push-6{left:50%}.col-xs-push-7{left:58.33333%}.col-xs-push-8{left:66.66667%}.col-xs-push-9{left:75%}.col-xs-push-10{left:83.33333%}.col-xs-push-11{left:91.66667%}.col-xs-push-12{left:100%}.col-xs-offset-0{margin-left:0%}.col-xs-offset-1{margin-left:8.33333%}.col-xs-offset-2{margin-left:16.66667%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-4{margin-left:33.33333%}.col-xs-offset-5{margin-left:41.66667%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-7{margin-left:58.33333%}.col-xs-offset-8{margin-left:66.66667%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-10{margin-left:83.33333%}.col-xs-offset-11{margin-left:91.66667%}.col-xs-offset-12{margin-left:100%}@media (min-width: 768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-1{width:8.33333%}.col-sm-2{width:16.66667%}.col-sm-3{width:25%}.col-sm-4{width:33.33333%}.col-sm-5{width:41.66667%}.col-sm-6{width:50%}.col-sm-7{width:58.33333%}.col-sm-8{width:66.66667%}.col-sm-9{width:75%}.col-sm-10{width:83.33333%}.col-sm-11{width:91.66667%}.col-sm-12{width:100%}.col-sm-pull-0{right:auto}.col-sm-pull-1{right:8.33333%}.col-sm-pull-2{right:16.66667%}.col-sm-pull-3{right:25%}.col-sm-pull-4{right:33.33333%}.col-sm-pull-5{right:41.66667%}.col-sm-pull-6{right:50%}.col-sm-pull-7{right:58.33333%}.col-sm-pull-8{right:66.66667%}.col-sm-pull-9{right:75%}.col-sm-pull-10{right:83.33333%}.col-sm-pull-11{right:91.66667%}.col-sm-pull-12{right:100%}.col-sm-push-0{left:auto}.col-sm-push-1{left:8.33333%}.col-sm-push-2{left:16.66667%}.col-sm-push-3{left:25%}.col-sm-push-4{left:33.33333%}.col-sm-push-5{left:41.66667%}.col-sm-push-6{left:50%}.col-sm-push-7{left:58.33333%}.col-sm-push-8{left:66.66667%}.col-sm-push-9{left:75%}.col-sm-push-10{left:83.33333%}.col-sm-push-11{left:91.66667%}.col-sm-push-12{left:100%}.col-sm-offset-0{margin-left:0%}.col-sm-offset-1{margin-left:8.33333%}.col-sm-offset-2{margin-left:16.66667%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-4{margin-left:33.33333%}.col-sm-offset-5{margin-left:41.66667%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-7{margin-left:58.33333%}.col-sm-offset-8{margin-left:66.66667%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-10{margin-left:83.33333%}.col-sm-offset-11{margin-left:91.66667%}.col-sm-offset-12{margin-left:100%}}@media (min-width: 992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-1{width:8.33333%}.col-md-2{width:16.66667%}.col-md-3{width:25%}.col-md-4{width:33.33333%}.col-md-5{width:41.66667%}.col-md-6{width:50%}.col-md-7{width:58.33333%}.col-md-8{width:66.66667%}.col-md-9{width:75%}.col-md-10{width:83.33333%}.col-md-11{width:91.66667%}.col-md-12{width:100%}.col-md-pull-0{right:auto}.col-md-pull-1{right:8.33333%}.col-md-pull-2{right:16.66667%}.col-md-pull-3{right:25%}.col-md-pull-4{right:33.33333%}.col-md-pull-5{right:41.66667%}.col-md-pull-6{right:50%}.col-md-pull-7{right:58.33333%}.col-md-pull-8{right:66.66667%}.col-md-pull-9{right:75%}.col-md-pull-10{right:83.33333%}.col-md-pull-11{right:91.66667%}.col-md-pull-12{right:100%}.col-md-push-0{left:auto}.col-md-push-1{left:8.33333%}.col-md-push-2{left:16.66667%}.col-md-push-3{left:25%}.col-md-push-4{left:33.33333%}.col-md-push-5{left:41.66667%}.col-md-push-6{left:50%}.col-md-push-7{left:58.33333%}.col-md-push-8{left:66.66667%}.col-md-push-9{left:75%}.col-md-push-10{left:83.33333%}.col-md-push-11{left:91.66667%}.col-md-push-12{left:100%}.col-md-offset-0{margin-left:0%}.col-md-offset-1{margin-left:8.33333%}.col-md-offset-2{margin-left:16.66667%}.col-md-offset-3{margin-left:25%}.col-md-offset-4{margin-left:33.33333%}.col-md-offset-5{margin-left:41.66667%}.col-md-offset-6{margin-left:50%}.col-md-offset-7{margin-left:58.33333%}.col-md-offset-8{margin-left:66.66667%}.col-md-offset-9{margin-left:75%}.col-md-offset-10{margin-left:83.33333%}.col-md-offset-11{margin-left:91.66667%}.col-md-offset-12{margin-left:100%}}@media (min-width: 1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-1{width:8.33333%}.col-lg-2{width:16.66667%}.col-lg-3{width:25%}.col-lg-4{width:33.33333%}.col-lg-5{width:41.66667%}.col-lg-6{width:50%}.col-lg-7{width:58.33333%}.col-lg-8{width:66.66667%}.col-lg-9{width:75%}.col-lg-10{width:83.33333%}.col-lg-11{width:91.66667%}.col-lg-12{width:100%}.col-lg-pull-0{right:auto}.col-lg-pull-1{right:8.33333%}.col-lg-pull-2{right:16.66667%}.col-lg-pull-3{right:25%}.col-lg-pull-4{right:33.33333%}.col-lg-pull-5{right:41.66667%}.col-lg-pull-6{right:50%}.col-lg-pull-7{right:58.33333%}.col-lg-pull-8{right:66.66667%}.col-lg-pull-9{right:75%}.col-lg-pull-10{right:83.33333%}.col-lg-pull-11{right:91.66667%}.col-lg-pull-12{right:100%}.col-lg-push-0{left:auto}.col-lg-push-1{left:8.33333%}.col-lg-push-2{left:16.66667%}.col-lg-push-3{left:25%}.col-lg-push-4{left:33.33333%}.col-lg-push-5{left:41.66667%}.col-lg-push-6{left:50%}.col-lg-push-7{left:58.33333%}.col-lg-push-8{left:66.66667%}.col-lg-push-9{left:75%}.col-lg-push-10{left:83.33333%}.col-lg-push-11{left:91.66667%}.col-lg-push-12{left:100%}.col-lg-offset-0{margin-left:0%}.col-lg-offset-1{margin-left:8.33333%}.col-lg-offset-2{margin-left:16.66667%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-4{margin-left:33.33333%}.col-lg-offset-5{margin-left:41.66667%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-7{margin-left:58.33333%}.col-lg-offset-8{margin-left:66.66667%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-10{margin-left:83.33333%}.col-lg-offset-11{margin-left:91.66667%}.col-lg-offset-12{margin-left:100%}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:18px}.table>thead>tr>th,.table>thead>tr>td,.table>tbody>tr>th,.table>tbody>tr>td,.table>tfoot>tr>th,.table>tfoot>tr>td{padding:8px;line-height:1.42857;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>th,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>tfoot>tr>td{padding:4px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>thead>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>thead>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>thead>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>thead>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>thead>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{overflow-x:auto;min-height:0.01%}@media screen and (max-width: 767px){.table-responsive{width:100%;margin-bottom:13.5px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:13px;line-height:1.42857;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn.focus,.btn:active:focus,.btn:active.focus,.btn.active:focus,.btn.active.focus{outline:thin dotted}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:focus,.btn-default.focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.btn-default.dropdown-toggle{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active:hover,.btn-default:active:focus,.btn-default:active.focus,.btn-default.active:hover,.btn-default.active:focus,.btn-default.active.focus,.open>.btn-default.dropdown-toggle:hover,.open>.btn-default.dropdown-toggle:focus,.open>.btn-default.dropdown-toggle.focus{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default:active,.btn-default.active,.open>.btn-default.dropdown-toggle{background-image:none}.btn-default.disabled:hover,.btn-default.disabled:focus,.btn-default.disabled.focus,.btn-default[disabled]:hover,.btn-default[disabled]:focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default:hover,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default.focus{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#B3231B;border-color:#9d1f18}.btn-primary:focus,.btn-primary.focus{color:#fff;background-color:#871a14;border-color:#2e0907}.btn-primary:hover{color:#fff;background-color:#871a14;border-color:#681410}.btn-primary:active,.btn-primary.active,.open>.btn-primary.dropdown-toggle{color:#fff;background-color:#871a14;border-color:#681410}.btn-primary:active:hover,.btn-primary:active:focus,.btn-primary:active.focus,.btn-primary.active:hover,.btn-primary.active:focus,.btn-primary.active.focus,.open>.btn-primary.dropdown-toggle:hover,.open>.btn-primary.dropdown-toggle:focus,.open>.btn-primary.dropdown-toggle.focus{color:#fff;background-color:#681410;border-color:#2e0907}.btn-primary:active,.btn-primary.active,.open>.btn-primary.dropdown-toggle{background-image:none}.btn-primary.disabled:hover,.btn-primary.disabled:focus,.btn-primary.disabled.focus,.btn-primary[disabled]:hover,.btn-primary[disabled]:focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary:hover,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary.focus{background-color:#B3231B;border-color:#9d1f18}.btn-primary .badge{color:#B3231B;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:focus,.btn-success.focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.btn-success.dropdown-toggle{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active:hover,.btn-success:active:focus,.btn-success:active.focus,.btn-success.active:hover,.btn-success.active:focus,.btn-success.active.focus,.open>.btn-success.dropdown-toggle:hover,.open>.btn-success.dropdown-toggle:focus,.open>.btn-success.dropdown-toggle.focus{color:#fff;background-color:#398439;border-color:#255625}.btn-success:active,.btn-success.active,.open>.btn-success.dropdown-toggle{background-image:none}.btn-success.disabled:hover,.btn-success.disabled:focus,.btn-success.disabled.focus,.btn-success[disabled]:hover,.btn-success[disabled]:focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success:hover,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success.focus{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:focus,.btn-info.focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.btn-info.dropdown-toggle{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active:hover,.btn-info:active:focus,.btn-info:active.focus,.btn-info.active:hover,.btn-info.active:focus,.btn-info.active.focus,.open>.btn-info.dropdown-toggle:hover,.open>.btn-info.dropdown-toggle:focus,.open>.btn-info.dropdown-toggle.focus{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info:active,.btn-info.active,.open>.btn-info.dropdown-toggle{background-image:none}.btn-info.disabled:hover,.btn-info.disabled:focus,.btn-info.disabled.focus,.btn-info[disabled]:hover,.btn-info[disabled]:focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info:hover,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info.focus{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:focus,.btn-warning.focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.btn-warning.dropdown-toggle{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active:hover,.btn-warning:active:focus,.btn-warning:active.focus,.btn-warning.active:hover,.btn-warning.active:focus,.btn-warning.active.focus,.open>.btn-warning.dropdown-toggle:hover,.open>.btn-warning.dropdown-toggle:focus,.open>.btn-warning.dropdown-toggle.focus{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning:active,.btn-warning.active,.open>.btn-warning.dropdown-toggle{background-image:none}.btn-warning.disabled:hover,.btn-warning.disabled:focus,.btn-warning.disabled.focus,.btn-warning[disabled]:hover,.btn-warning[disabled]:focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning:hover,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning.focus{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:focus,.btn-danger.focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.btn-danger.dropdown-toggle{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active:hover,.btn-danger:active:focus,.btn-danger:active.focus,.btn-danger.active:hover,.btn-danger.active:focus,.btn-danger.active.focus,.open>.btn-danger.dropdown-toggle:hover,.open>.btn-danger.dropdown-toggle:focus,.open>.btn-danger.dropdown-toggle.focus{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger:active,.btn-danger.active,.open>.btn-danger.dropdown-toggle{background-image:none}.btn-danger.disabled:hover,.btn-danger.disabled:focus,.btn-danger.disabled.focus,.btn-danger[disabled]:hover,.btn-danger[disabled]:focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger:hover,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger.focus{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#B3231B;font-weight:normal;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#711611;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:hover,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:17px;line-height:1.33333;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \9;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:13px;text-align:left;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:8px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.42857;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#B3231B}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid \9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width: 768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn:hover,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar:before,.btn-toolbar:after{content:" ";display:table}.btn-toolbar:after{clear:both}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle,.btn-group-lg.btn-group>.btn+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret,.btn-group-lg>.btn .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret,.dropup .btn-group-lg>.btn .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{content:" ";display:table}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle="buttons"]>.btn input[type="radio"],[data-toggle="buttons"]>.btn input[type="checkbox"],[data-toggle="buttons"]>.btn-group>.btn input[type="radio"],[data-toggle="buttons"]>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav:before,.nav:after{content:" ";display:table}.nav:after{clear:both}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:8px 13px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#B3231B}.nav .nav-divider{height:1px;margin:8px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#B3231B}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified,.nav-tabs.nav-justified{width:100%}.nav-justified>li,.nav-tabs.nav-justified>li{float:none}.nav-justified>li>a,.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width: 768px){.nav-justified>li,.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a,.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified,.nav-tabs.nav-justified{border-bottom:0}.nav-tabs-justified>li>a,.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs.nav-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width: 768px){.nav-tabs-justified>li>a,.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs.nav-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:18px;border:1px solid transparent}.navbar:before,.navbar:after{content:" ";display:table}.navbar:after{clear:both}@media (min-width: 768px){.navbar{border-radius:4px}}.navbar-header:before,.navbar-header:after{content:" ";display:table}.navbar-header:after{clear:both}@media (min-width: 768px){.navbar-header{float:left}}.navbar-collapse{overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse:before,.navbar-collapse:after{content:" ";display:table}.navbar-collapse:after{clear:both}.navbar-collapse.in{overflow-y:auto}@media (min-width: 768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block !important;height:auto !important;padding-bottom:0;overflow:visible !important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width: 480px) and (orientation: landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-header,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width: 768px){.container>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-header,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width: 768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width: 768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:16px 15px;font-size:17px;line-height:18px;height:50px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width: 768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width: 768px){.navbar-toggle{display:none}}.navbar-nav{margin:8px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:18px}@media (max-width: 767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:18px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width: 768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:16px;padding-bottom:16px}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);margin-top:9px;margin-bottom:9px}@media (max-width: 767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width: 768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:9px;margin-bottom:9px}.navbar-btn.btn-sm,.btn-group-sm>.navbar-btn.btn{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs,.btn-group-xs>.navbar-btn.btn{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:16px;margin-bottom:16px}@media (min-width: 768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}}@media (min-width: 768px){.navbar-left{float:left !important}.navbar-right{float:right !important;margin-right:-15px}.navbar-right ~ .navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#e7e7e7;color:#555}@media (max-width: 767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:hover,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#535250;border-color:#393837}.navbar-inverse .navbar-brand{color:#ADADAD}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#ADADAD}.navbar-inverse .navbar-nav>li>a{color:#ADADAD}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#393837}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#41403e}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#393837;color:#fff}@media (max-width: 767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#393837}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#393837}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#ADADAD}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#393837}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#ADADAD}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#ADADAD}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:hover,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.close{float:right;font-size:19.5px;font-weight:bold;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:0.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:0.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:hidden;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);-o-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform 0.3s ease-out;-moz-transition:-moz-transform 0.3s ease-out;-o-transition:-o-transform 0.3s ease-out;transition:transform 0.3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:0.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header:before,.modal-header:after{content:" ";display:table}.modal-header:after{clear:both}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer:before,.modal-footer:after{content:" ";display:table}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width: 768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}.modal-sm{width:300px}}@media (min-width: 992px){.modal-lg{width:900px}}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs{display:none !important}.visible-sm{display:none !important}.visible-md{display:none !important}.visible-lg{display:none !important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none !important}@media (max-width: 767px){.visible-xs{display:block !important}table.visible-xs{display:table !important}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (max-width: 767px){.visible-xs-block{display:block !important}}@media (max-width: 767px){.visible-xs-inline{display:inline !important}}@media (max-width: 767px){.visible-xs-inline-block{display:inline-block !important}}@media (min-width: 768px) and (max-width: 991px){.visible-sm{display:block !important}table.visible-sm{display:table !important}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width: 768px) and (max-width: 991px){.visible-sm-block{display:block !important}}@media (min-width: 768px) and (max-width: 991px){.visible-sm-inline{display:inline !important}}@media (min-width: 768px) and (max-width: 991px){.visible-sm-inline-block{display:inline-block !important}}@media (min-width: 992px) and (max-width: 1199px){.visible-md{display:block !important}table.visible-md{display:table !important}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width: 992px) and (max-width: 1199px){.visible-md-block{display:block !important}}@media (min-width: 992px) and (max-width: 1199px){.visible-md-inline{display:inline !important}}@media (min-width: 992px) and (max-width: 1199px){.visible-md-inline-block{display:inline-block !important}}@media (min-width: 1200px){.visible-lg{display:block !important}table.visible-lg{display:table !important}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (min-width: 1200px){.visible-lg-block{display:block !important}}@media (min-width: 1200px){.visible-lg-inline{display:inline !important}}@media (min-width: 1200px){.visible-lg-inline-block{display:inline-block !important}}@media (max-width: 767px){.hidden-xs{display:none !important}}@media (min-width: 768px) and (max-width: 991px){.hidden-sm{display:none !important}}@media (min-width: 992px) and (max-width: 1199px){.hidden-md{display:none !important}}@media (min-width: 1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table !important}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}}.visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}}.visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}@media print{.hidden-print{display:none !important}} diff --git a/votrfront/css/dist/votr.css b/votrfront/css/dist/votr.css new file mode 100644 index 0000000..cc9ec30 --- /dev/null +++ b/votrfront/css/dist/votr.css @@ -0,0 +1 @@ +@media (min-width: 992px){.layout-container{position:relative;padding-left:200px}.layout-container:before,.layout-container:after{content:" ";display:table}.layout-container:after{clear:both}.layout-menu{float:left;margin-left:-200px;width:200px;padding:0 5px}.layout-menu:after{content:" ";position:absolute;z-index:-1;left:0;top:0;width:200px;height:100%;border-right:solid #eee 1px}.layout-content{float:left;width:100%;padding-bottom:2em}}@media (max-width: 991px){.layout-menu{padding:15px;max-width:400px}}.form-item{display:block;margin-bottom:9px;margin-left:-15px;margin-right:-15px;max-width:40em}.form-item:before,.form-item:after{content:" ";display:table}.form-item:after{clear:both}.form-item-label{display:block;font-weight:bold;margin-bottom:5px}@media (min-width: 768px){.form-item-label{text-align:right;margin-bottom:0}}.form-item-control{display:block;width:100%}.form-item.has-error{color:#a94442}.form-item.has-error input,.form-item.has-error select,.form-item.has-error textarea{border:solid #a94442 1px}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;line-height:normal}html,body{position:relative;height:100%}body,.modal-open .modal{overflow-y:scroll}a,.btn.btn-link{text-decoration:underline;cursor:pointer}.nav a,a.btn{text-decoration:none}.nav .disabled a{text-decoration:line-through !important;cursor:auto !important}.navbar-brand{text-decoration:none;font-weight:bold}.text-pill{position:relative;display:block;padding:8px 13px}.selector{background:#eee;padding:3px;border-radius:6px;display:inline-block}.selector li a:hover,.selector li a:focus{background-color:#ddd}.selector .text-pill{color:#777}.header{margin-top:18px;margin-bottom:18px}.header:before,.header:after{content:" ";display:table}.header:after{clear:both}.header h1{margin:0;float:left}.section{margin-top:18px;margin-bottom:18px}.loading{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxnPgogICAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogICAgPGc+PHJlY3QgaGVpZ2h0PSI4IiB3aWR0aD0iMi41IiBmaWxsPSIjMjMxRjIwIiB4PSIxNC43NSIvPjwvZz4KICAgIDxnPjxyZWN0IGhlaWdodD0iMi41IiB3aWR0aD0iOCIgZmlsbD0iIzQxNDA0MiIgdHJhbnNmb3JtPSJtYXRyaXgoMC41LDAuODY2LC0wLjg2NiwwLjUsOS44NTY0LC01Ljg1NjQpICIgeT0iNC4zNTgiIHg9IjYiLz48L2c+CiAgICA8Zz48cmVjdCBoZWlnaHQ9IjIuNSIgd2lkdGg9IjgiIGZpbGw9IiM1ODU5NUIiIHRyYW5zZm9ybT0ibWF0cml4KDAuODY2LDAuNSwtMC41LDAuODY2LDUuNzUxNywtMS40NjQ0KSAiIHk9IjguNzUiIHg9IjEuNjA5Ii8+PC9nPgogICAgPGc+PHJlY3QgaGVpZ2h0PSIyLjUiIHdpZHRoPSI4IiBmaWxsPSIjNkQ2RTcxIiB5PSIxNC43NSIvPjwvZz4KICAgIDxnPjxyZWN0IGhlaWdodD0iOCIgd2lkdGg9IjIuNSIgZmlsbD0iIzgwODI4NSIgdHJhbnNmb3JtPSJtYXRyaXgoMC40OTk4LDAuODY2MSwtMC44NjYxLDAuNDk5OCwyMS44NTk4LDYuMTQ1KSAiIHk9IjE4IiB4PSI0LjM1OSIvPjwvZz4KICAgIDxnPjxyZWN0IGhlaWdodD0iOCIgd2lkdGg9IjIuNSIgZmlsbD0iIzkzOTU5OCIgdHJhbnNmb3JtPSJtYXRyaXgoMC44NjYsMC41LC0wLjUsMC44NjYsMTQuNTM1OSwtMS40NjUxKSAiIHk9IjIyLjM5MiIgeD0iOC43NTIiLz48L2c+CiAgICA8Zz48cmVjdCBoZWlnaHQ9IjgiIHdpZHRoPSIyLjUiIGZpbGw9IiNBN0E5QUMiIHk9IjI0IiB4PSIxNC43NTIiLz48L2c+CiAgICA8Zz48cmVjdCBoZWlnaHQ9IjIuNSIgd2lkdGg9IjgiIGZpbGw9IiNCQ0JFQzAiIHRyYW5zZm9ybT0ibWF0cml4KDAuNTAwMSwwLjg2NiwtMC44NjYsMC41MDAxLDMzLjg1MjYsLTUuODYwMykgIiB5PSIyNS4xNDEiIHg9IjE4LjAwMyIvPjwvZz4KICAgIDxnPjxyZWN0IGhlaWdodD0iMi41IiB3aWR0aD0iOCIgZmlsbD0iI0QxRDNENCIgdHJhbnNmb3JtPSJtYXRyaXgoMC44NjYxLDAuNDk5OCwtMC40OTk4LDAuODY2MSwxNC41Mjg3LC0xMC4yNDc2KSAiIHk9IjIwLjc0NyIgeD0iMjIuMzk0Ii8+PC9nPgogICAgPGc+PHJlY3QgaGVpZ2h0PSIyLjUiIHdpZHRoPSI4IiBmaWxsPSIjRTZFN0U4IiB5PSIxNC43NDciIHg9IjI0LjAwMSIvPjwvZz4KICAgIDxnPjxyZWN0IGhlaWdodD0iOCIgd2lkdGg9IjIuNSIgZmlsbD0iI0U2RTdFOCIgdHJhbnNmb3JtPSJtYXRyaXgoMC41LDAuODY2LC0wLjg2NiwwLjUsMjEuODUzNiwtMTcuODU3NykgIiB5PSI1Ljk5NyIgeD0iMjUuMTQyIi8+PC9nPgogICAgPGc+PHJlY3QgaGVpZ2h0PSI4IiB3aWR0aD0iMi41IiBmaWxsPSIjRTZFN0U4IiB0cmFuc2Zvcm09Im1hdHJpeCgwLjg2NjMsMC40OTk1LC0wLjQ5OTUsMC44NjYzLDUuNzQxNywtMTAuMjM5OSkgIiB5PSIxLjYwNiIgeD0iMjAuNzQ5Ii8+PC9nPgogICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiBhdHRyaWJ1dGVUeXBlPSJYTUwiIHR5cGU9InJvdGF0ZSIgZnJvbT0iMCAxNiAxNiIgdG89IjM2MCAxNiAxNiIgYmVnaW49IjBzIiBkdXI9IjFzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIvPgogIDwvZz4KPC9zdmc+Cg==);background-repeat:no-repeat;background-size:contain;padding-left:1.5em}.table-bordered th,.table-bordered td{border-left-style:none !important;border-right-style:none !important}.table-narrow{width:auto}th.sort{cursor:pointer}th.sort.asc,th.sort.desc{background:#eee}th.sort:after{content:"\00a0↕";visibility:hidden}th.sort.asc:after{content:"\00a0↑";visibility:visible}th.sort.desc:after{content:"\00a0↓";visibility:visible}.log-viewer{position:fixed;left:5em;right:5em;bottom:0;height:20em;max-height:70%;z-index:1111;background:#eee;border:solid #777 2px;border-bottom:0}.log-viewer .options,.log-viewer .right{position:absolute;bottom:100%;margin:0 1em;background:#eee;border:solid #777 2px;border-bottom:0}.log-viewer .right{padding:0.5em;right:0}.log-viewer .scroll{height:100%;padding:1em;overflow:auto}.login-page{display:flex;flex-direction:column;justify-content:space-between;min-height:100%}.login-page .login-content{max-width:30em;padding:2em 15px;margin:auto;align-self:center}.login-page .list-inline a{color:#777}.login-page .list-inline a:hover{color:#333}.central-box{position:absolute;left:1em;right:1em;top:30%;text-align:center}thead:empty,tbody:empty,tfoot:empty{display:none}.table.with-buttons-table td{vertical-align:middle}.text-positive{color:#23b823}.text-negative{color:#b3231b}.appear-disabled{opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none} diff --git a/votrfront/css/_forms.scss b/votrfront/css/src/_forms.scss similarity index 100% rename from votrfront/css/_forms.scss rename to votrfront/css/src/_forms.scss diff --git a/votrfront/css/_layout.scss b/votrfront/css/src/_layout.scss similarity index 100% rename from votrfront/css/_layout.scss rename to votrfront/css/src/_layout.scss diff --git a/votrfront/css/src/_mixins.scss b/votrfront/css/src/_mixins.scss new file mode 100644 index 0000000..78cd5aa --- /dev/null +++ b/votrfront/css/src/_mixins.scss @@ -0,0 +1,40 @@ +// Mixins +// -------------------------------------------------- + +// Utilities +@import "mixins/hide-text"; +@import "mixins/opacity"; +@import "mixins/image"; +@import "mixins/labels"; +@import "mixins/reset-filter"; +@import "mixins/resize"; +@import "mixins/responsive-visibility"; +@import "mixins/size"; +@import "mixins/tab-focus"; +@import "mixins/reset-text"; +@import "mixins/text-emphasis"; +@import "mixins/text-overflow"; +@import "mixins/vendor-prefixes"; + +// Components +@import "mixins/alerts"; +@import "mixins/buttons"; +@import "mixins/panels"; +@import "mixins/pagination"; +@import "mixins/list-group"; +@import "mixins/nav-divider"; +@import "mixins/forms"; +@import "mixins/progress-bar"; +@import "mixins/table-row"; + +// Skins +@import "mixins/background-variant"; +@import "mixins/border-radius"; +@import "mixins/gradients"; + +// Layout +@import "mixins/clearfix"; +@import "mixins/center-block"; +@import "mixins/nav-vertical-align"; +@import "mixins/grid-framework"; +@import "mixins/grid"; diff --git a/votrfront/css/src/_spinner.scss b/votrfront/css/src/_spinner.scss new file mode 100644 index 0000000..7146ad5 --- /dev/null +++ b/votrfront/css/src/_spinner.scss @@ -0,0 +1 @@ +$spinner: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxnPgogICAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogICAgPGc+PHJlY3QgaGVpZ2h0PSI4IiB3aWR0aD0iMi41IiBmaWxsPSIjMjMxRjIwIiB4PSIxNC43NSIvPjwvZz4KICAgIDxnPjxyZWN0IGhlaWdodD0iMi41IiB3aWR0aD0iOCIgZmlsbD0iIzQxNDA0MiIgdHJhbnNmb3JtPSJtYXRyaXgoMC41LDAuODY2LC0wLjg2NiwwLjUsOS44NTY0LC01Ljg1NjQpICIgeT0iNC4zNTgiIHg9IjYiLz48L2c+CiAgICA8Zz48cmVjdCBoZWlnaHQ9IjIuNSIgd2lkdGg9IjgiIGZpbGw9IiM1ODU5NUIiIHRyYW5zZm9ybT0ibWF0cml4KDAuODY2LDAuNSwtMC41LDAuODY2LDUuNzUxNywtMS40NjQ0KSAiIHk9IjguNzUiIHg9IjEuNjA5Ii8+PC9nPgogICAgPGc+PHJlY3QgaGVpZ2h0PSIyLjUiIHdpZHRoPSI4IiBmaWxsPSIjNkQ2RTcxIiB5PSIxNC43NSIvPjwvZz4KICAgIDxnPjxyZWN0IGhlaWdodD0iOCIgd2lkdGg9IjIuNSIgZmlsbD0iIzgwODI4NSIgdHJhbnNmb3JtPSJtYXRyaXgoMC40OTk4LDAuODY2MSwtMC44NjYxLDAuNDk5OCwyMS44NTk4LDYuMTQ1KSAiIHk9IjE4IiB4PSI0LjM1OSIvPjwvZz4KICAgIDxnPjxyZWN0IGhlaWdodD0iOCIgd2lkdGg9IjIuNSIgZmlsbD0iIzkzOTU5OCIgdHJhbnNmb3JtPSJtYXRyaXgoMC44NjYsMC41LC0wLjUsMC44NjYsMTQuNTM1OSwtMS40NjUxKSAiIHk9IjIyLjM5MiIgeD0iOC43NTIiLz48L2c+CiAgICA8Zz48cmVjdCBoZWlnaHQ9IjgiIHdpZHRoPSIyLjUiIGZpbGw9IiNBN0E5QUMiIHk9IjI0IiB4PSIxNC43NTIiLz48L2c+CiAgICA8Zz48cmVjdCBoZWlnaHQ9IjIuNSIgd2lkdGg9IjgiIGZpbGw9IiNCQ0JFQzAiIHRyYW5zZm9ybT0ibWF0cml4KDAuNTAwMSwwLjg2NiwtMC44NjYsMC41MDAxLDMzLjg1MjYsLTUuODYwMykgIiB5PSIyNS4xNDEiIHg9IjE4LjAwMyIvPjwvZz4KICAgIDxnPjxyZWN0IGhlaWdodD0iMi41IiB3aWR0aD0iOCIgZmlsbD0iI0QxRDNENCIgdHJhbnNmb3JtPSJtYXRyaXgoMC44NjYxLDAuNDk5OCwtMC40OTk4LDAuODY2MSwxNC41Mjg3LC0xMC4yNDc2KSAiIHk9IjIwLjc0NyIgeD0iMjIuMzk0Ii8+PC9nPgogICAgPGc+PHJlY3QgaGVpZ2h0PSIyLjUiIHdpZHRoPSI4IiBmaWxsPSIjRTZFN0U4IiB5PSIxNC43NDciIHg9IjI0LjAwMSIvPjwvZz4KICAgIDxnPjxyZWN0IGhlaWdodD0iOCIgd2lkdGg9IjIuNSIgZmlsbD0iI0U2RTdFOCIgdHJhbnNmb3JtPSJtYXRyaXgoMC41LDAuODY2LC0wLjg2NiwwLjUsMjEuODUzNiwtMTcuODU3NykgIiB5PSI1Ljk5NyIgeD0iMjUuMTQyIi8+PC9nPgogICAgPGc+PHJlY3QgaGVpZ2h0PSI4IiB3aWR0aD0iMi41IiBmaWxsPSIjRTZFN0U4IiB0cmFuc2Zvcm09Im1hdHJpeCgwLjg2NjMsMC40OTk1LC0wLjQ5OTUsMC44NjYzLDUuNzQxNywtMTAuMjM5OSkgIiB5PSIxLjYwNiIgeD0iMjAuNzQ5Ii8+PC9nPgogICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiBhdHRyaWJ1dGVUeXBlPSJYTUwiIHR5cGU9InJvdGF0ZSIgZnJvbT0iMCAxNiAxNiIgdG89IjM2MCAxNiAxNiIgYmVnaW49IjBzIiBkdXI9IjFzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIvPgogIDwvZz4KPC9zdmc+Cg==); diff --git a/votrfront/css/src/_variables.scss b/votrfront/css/src/_variables.scss new file mode 100644 index 0000000..e049685 --- /dev/null +++ b/votrfront/css/src/_variables.scss @@ -0,0 +1,874 @@ +$bootstrap-sass-asset-helper: false !default; +// +// Variables +// -------------------------------------------------- + + +//== Colors +// +//## Gray and brand colors for use across Bootstrap. + +$gray-base: #000 !default; +$gray-darker: lighten($gray-base, 13.5%) !default; // #222 +$gray-dark: lighten($gray-base, 20%) !default; // #333 +$gray: lighten($gray-base, 33.5%) !default; // #555 +$gray-light: lighten($gray-base, 46.7%) !default; // #777 +$gray-lighter: lighten($gray-base, 93.5%) !default; // #eee + +$brand-primary: darken(#428bca, 6.5%) !default; // #337ab7 +$brand-success: #5cb85c !default; +$brand-info: #5bc0de !default; +$brand-warning: #f0ad4e !default; +$brand-danger: #d9534f !default; + + +//== Scaffolding +// +//## Settings for some of the most global styles. + +//** Background color for ``. +$body-bg: #fff !default; +//** Global text color on ``. +$text-color: $gray-dark !default; + +//** Global textual link color. +$link-color: $brand-primary !default; +//** Link hover color set via `darken()` function. +$link-hover-color: darken($link-color, 15%) !default; +//** Link hover decoration. +$link-hover-decoration: underline !default; + + +//== Typography +// +//## Font, line-height, and color for body text, headings, and more. + +$font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif !default; +$font-family-serif: Georgia, "Times New Roman", Times, serif !default; +//** Default monospace fonts for ``, ``, and `
`.
+$font-family-monospace:   Menlo, Monaco, Consolas, "Courier New", monospace !default;
+$font-family-base:        $font-family-sans-serif !default;
+
+$font-size-base:          14px !default;
+$font-size-large:         ceil(($font-size-base * 1.25)) !default; // ~18px
+$font-size-small:         ceil(($font-size-base * 0.85)) !default; // ~12px
+
+$font-size-h1:            floor(($font-size-base * 2.6)) !default; // ~36px
+$font-size-h2:            floor(($font-size-base * 2.15)) !default; // ~30px
+$font-size-h3:            ceil(($font-size-base * 1.7)) !default; // ~24px
+$font-size-h4:            ceil(($font-size-base * 1.25)) !default; // ~18px
+$font-size-h5:            $font-size-base !default;
+$font-size-h6:            ceil(($font-size-base * 0.85)) !default; // ~12px
+
+//** Unit-less `line-height` for use in components like buttons.
+$line-height-base:        1.428571429 !default; // 20/14
+//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
+$line-height-computed:    floor(($font-size-base * $line-height-base)) !default; // ~20px
+
+//** By default, this inherits from the ``.
+$headings-font-family:    inherit !default;
+$headings-font-weight:    500 !default;
+$headings-line-height:    1.1 !default;
+$headings-color:          inherit !default;
+
+
+//== Iconography
+//
+//## Specify custom location and filename of the included Glyphicons icon font. Useful for those including Bootstrap via Bower.
+
+//** Load fonts from this directory.
+
+// [converter] If $bootstrap-sass-asset-helper if used, provide path relative to the assets load path.
+// [converter] This is because some asset helpers, such as Sprockets, do not work with file-relative paths.
+$icon-font-path: if($bootstrap-sass-asset-helper, "bootstrap/", "../fonts/bootstrap/") !default;
+
+//** File name for all font files.
+$icon-font-name:          "glyphicons-halflings-regular" !default;
+//** Element ID within SVG icon file.
+$icon-font-svg-id:        "glyphicons_halflingsregular" !default;
+
+
+//== Components
+//
+//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
+
+$padding-base-vertical:     6px !default;
+$padding-base-horizontal:   12px !default;
+
+$padding-large-vertical:    10px !default;
+$padding-large-horizontal:  16px !default;
+
+$padding-small-vertical:    5px !default;
+$padding-small-horizontal:  10px !default;
+
+$padding-xs-vertical:       1px !default;
+$padding-xs-horizontal:     5px !default;
+
+$line-height-large:         1.3333333 !default; // extra decimals for Win 8.1 Chrome
+$line-height-small:         1.5 !default;
+
+$border-radius-base:        4px !default;
+$border-radius-large:       6px !default;
+$border-radius-small:       3px !default;
+
+//** Global color for active items (e.g., navs or dropdowns).
+$component-active-color:    #fff !default;
+//** Global background color for active items (e.g., navs or dropdowns).
+$component-active-bg:       $brand-primary !default;
+
+//** Width of the `border` for generating carets that indicate dropdowns.
+$caret-width-base:          4px !default;
+//** Carets increase slightly in size for larger components.
+$caret-width-large:         5px !default;
+
+
+//== Tables
+//
+//## Customizes the `.table` component with basic values, each used across all table variations.
+
+//** Padding for ``s and ``s.
+$table-cell-padding:            8px !default;
+//** Padding for cells in `.table-condensed`.
+$table-condensed-cell-padding:  5px !default;
+
+//** Default background color used for all tables.
+$table-bg:                      transparent !default;
+//** Background color used for `.table-striped`.
+$table-bg-accent:               #f9f9f9 !default;
+//** Background color used for `.table-hover`.
+$table-bg-hover:                #f5f5f5 !default;
+$table-bg-active:               $table-bg-hover !default;
+
+//** Border color for table and cell borders.
+$table-border-color:            #ddd !default;
+
+
+//== Buttons
+//
+//## For each of Bootstrap's buttons, define text, background and border color.
+
+$btn-font-weight:                normal !default;
+
+$btn-default-color:              #333 !default;
+$btn-default-bg:                 #fff !default;
+$btn-default-border:             #ccc !default;
+
+$btn-primary-color:              #fff !default;
+$btn-primary-bg:                 $brand-primary !default;
+$btn-primary-border:             darken($btn-primary-bg, 5%) !default;
+
+$btn-success-color:              #fff !default;
+$btn-success-bg:                 $brand-success !default;
+$btn-success-border:             darken($btn-success-bg, 5%) !default;
+
+$btn-info-color:                 #fff !default;
+$btn-info-bg:                    $brand-info !default;
+$btn-info-border:                darken($btn-info-bg, 5%) !default;
+
+$btn-warning-color:              #fff !default;
+$btn-warning-bg:                 $brand-warning !default;
+$btn-warning-border:             darken($btn-warning-bg, 5%) !default;
+
+$btn-danger-color:               #fff !default;
+$btn-danger-bg:                  $brand-danger !default;
+$btn-danger-border:              darken($btn-danger-bg, 5%) !default;
+
+$btn-link-disabled-color:        $gray-light !default;
+
+// Allows for customizing button radius independently from global border radius
+$btn-border-radius-base:         $border-radius-base !default;
+$btn-border-radius-large:        $border-radius-large !default;
+$btn-border-radius-small:        $border-radius-small !default;
+
+
+//== Forms
+//
+//##
+
+//** `` background color
+$input-bg:                       #fff !default;
+//** `` background color
+$input-bg-disabled:              $gray-lighter !default;
+
+//** Text color for ``s
+$input-color:                    $gray !default;
+//** `` border color
+$input-border:                   #ccc !default;
+
+// TODO: Rename `$input-border-radius` to `$input-border-radius-base` in v4
+//** Default `.form-control` border radius
+// This has no effect on ``s in CSS.
+$input-border-radius:            $border-radius-base !default;
+//** Large `.form-control` border radius
+$input-border-radius-large:      $border-radius-large !default;
+//** Small `.form-control` border radius
+$input-border-radius-small:      $border-radius-small !default;
+
+//** Border color for inputs on focus
+$input-border-focus:             #66afe9 !default;
+
+//** Placeholder text color
+$input-color-placeholder:        #999 !default;
+
+//** Default `.form-control` height
+$input-height-base:              ($line-height-computed + ($padding-base-vertical * 2) + 2) !default;
+//** Large `.form-control` height
+$input-height-large:             (ceil($font-size-large * $line-height-large) + ($padding-large-vertical * 2) + 2) !default;
+//** Small `.form-control` height
+$input-height-small:             (floor($font-size-small * $line-height-small) + ($padding-small-vertical * 2) + 2) !default;
+
+//** `.form-group` margin
+$form-group-margin-bottom:       15px !default;
+
+$legend-color:                   $gray-dark !default;
+$legend-border-color:            #e5e5e5 !default;
+
+//** Background color for textual input addons
+$input-group-addon-bg:           $gray-lighter !default;
+//** Border color for textual input addons
+$input-group-addon-border-color: $input-border !default;
+
+//** Disabled cursor for form controls and buttons.
+$cursor-disabled:                not-allowed !default;
+
+
+//== Dropdowns
+//
+//## Dropdown menu container and contents.
+
+//** Background for the dropdown menu.
+$dropdown-bg:                    #fff !default;
+//** Dropdown menu `border-color`.
+$dropdown-border:                rgba(0,0,0,.15) !default;
+//** Dropdown menu `border-color` **for IE8**.
+$dropdown-fallback-border:       #ccc !default;
+//** Divider color for between dropdown items.
+$dropdown-divider-bg:            #e5e5e5 !default;
+
+//** Dropdown link text color.
+$dropdown-link-color:            $gray-dark !default;
+//** Hover color for dropdown links.
+$dropdown-link-hover-color:      darken($gray-dark, 5%) !default;
+//** Hover background for dropdown links.
+$dropdown-link-hover-bg:         #f5f5f5 !default;
+
+//** Active dropdown menu item text color.
+$dropdown-link-active-color:     $component-active-color !default;
+//** Active dropdown menu item background color.
+$dropdown-link-active-bg:        $component-active-bg !default;
+
+//** Disabled dropdown menu item background color.
+$dropdown-link-disabled-color:   $gray-light !default;
+
+//** Text color for headers within dropdown menus.
+$dropdown-header-color:          $gray-light !default;
+
+//** Deprecated `$dropdown-caret-color` as of v3.1.0
+$dropdown-caret-color:           #000 !default;
+
+
+//-- Z-index master list
+//
+// Warning: Avoid customizing these values. They're used for a bird's eye view
+// of components dependent on the z-axis and are designed to all work together.
+//
+// Note: These variables are not generated into the Customizer.
+
+$zindex-navbar:            1000 !default;
+$zindex-dropdown:          1000 !default;
+$zindex-popover:           1060 !default;
+$zindex-tooltip:           1070 !default;
+$zindex-navbar-fixed:      1030 !default;
+$zindex-modal-background:  1040 !default;
+$zindex-modal:             1050 !default;
+
+
+//== Media queries breakpoints
+//
+//## Define the breakpoints at which your layout will change, adapting to different screen sizes.
+
+// Extra small screen / phone
+//** Deprecated `$screen-xs` as of v3.0.1
+$screen-xs:                  480px !default;
+//** Deprecated `$screen-xs-min` as of v3.2.0
+$screen-xs-min:              $screen-xs !default;
+//** Deprecated `$screen-phone` as of v3.0.1
+$screen-phone:               $screen-xs-min !default;
+
+// Small screen / tablet
+//** Deprecated `$screen-sm` as of v3.0.1
+$screen-sm:                  768px !default;
+$screen-sm-min:              $screen-sm !default;
+//** Deprecated `$screen-tablet` as of v3.0.1
+$screen-tablet:              $screen-sm-min !default;
+
+// Medium screen / desktop
+//** Deprecated `$screen-md` as of v3.0.1
+$screen-md:                  992px !default;
+$screen-md-min:              $screen-md !default;
+//** Deprecated `$screen-desktop` as of v3.0.1
+$screen-desktop:             $screen-md-min !default;
+
+// Large screen / wide desktop
+//** Deprecated `$screen-lg` as of v3.0.1
+$screen-lg:                  1200px !default;
+$screen-lg-min:              $screen-lg !default;
+//** Deprecated `$screen-lg-desktop` as of v3.0.1
+$screen-lg-desktop:          $screen-lg-min !default;
+
+// So media queries don't overlap when required, provide a maximum
+$screen-xs-max:              ($screen-sm-min - 1) !default;
+$screen-sm-max:              ($screen-md-min - 1) !default;
+$screen-md-max:              ($screen-lg-min - 1) !default;
+
+
+//== Grid system
+//
+//## Define your custom responsive grid.
+
+//** Number of columns in the grid.
+$grid-columns:              12 !default;
+//** Padding between columns. Gets divided in half for the left and right.
+$grid-gutter-width:         30px !default;
+// Navbar collapse
+//** Point at which the navbar becomes uncollapsed.
+$grid-float-breakpoint:     $screen-sm-min !default;
+//** Point at which the navbar begins collapsing.
+$grid-float-breakpoint-max: ($grid-float-breakpoint - 1) !default;
+
+
+//== Container sizes
+//
+//## Define the maximum width of `.container` for different screen sizes.
+
+// Small screen / tablet
+$container-tablet:             (720px + $grid-gutter-width) !default;
+//** For `$screen-sm-min` and up.
+$container-sm:                 $container-tablet !default;
+
+// Medium screen / desktop
+$container-desktop:            (940px + $grid-gutter-width) !default;
+//** For `$screen-md-min` and up.
+$container-md:                 $container-desktop !default;
+
+// Large screen / wide desktop
+$container-large-desktop:      (1140px + $grid-gutter-width) !default;
+//** For `$screen-lg-min` and up.
+$container-lg:                 $container-large-desktop !default;
+
+
+//== Navbar
+//
+//##
+
+// Basics of a navbar
+$navbar-height:                    50px !default;
+$navbar-margin-bottom:             $line-height-computed !default;
+$navbar-border-radius:             $border-radius-base !default;
+$navbar-padding-horizontal:        floor(($grid-gutter-width / 2)) !default;
+$navbar-padding-vertical:          (($navbar-height - $line-height-computed) / 2) !default;
+$navbar-collapse-max-height:       340px !default;
+
+$navbar-default-color:             #777 !default;
+$navbar-default-bg:                #f8f8f8 !default;
+$navbar-default-border:            darken($navbar-default-bg, 6.5%) !default;
+
+// Navbar links
+$navbar-default-link-color:                #777 !default;
+$navbar-default-link-hover-color:          #333 !default;
+$navbar-default-link-hover-bg:             transparent !default;
+$navbar-default-link-active-color:         #555 !default;
+$navbar-default-link-active-bg:            darken($navbar-default-bg, 6.5%) !default;
+$navbar-default-link-disabled-color:       #ccc !default;
+$navbar-default-link-disabled-bg:          transparent !default;
+
+// Navbar brand label
+$navbar-default-brand-color:               $navbar-default-link-color !default;
+$navbar-default-brand-hover-color:         darken($navbar-default-brand-color, 10%) !default;
+$navbar-default-brand-hover-bg:            transparent !default;
+
+// Navbar toggle
+$navbar-default-toggle-hover-bg:           #ddd !default;
+$navbar-default-toggle-icon-bar-bg:        #888 !default;
+$navbar-default-toggle-border-color:       #ddd !default;
+
+
+//=== Inverted navbar
+// Reset inverted navbar basics
+$navbar-inverse-color:                      lighten($gray-light, 15%) !default;
+$navbar-inverse-bg:                         #222 !default;
+$navbar-inverse-border:                     darken($navbar-inverse-bg, 10%) !default;
+
+// Inverted navbar links
+$navbar-inverse-link-color:                 lighten($gray-light, 15%) !default;
+$navbar-inverse-link-hover-color:           #fff !default;
+$navbar-inverse-link-hover-bg:              transparent !default;
+$navbar-inverse-link-active-color:          $navbar-inverse-link-hover-color !default;
+$navbar-inverse-link-active-bg:             darken($navbar-inverse-bg, 10%) !default;
+$navbar-inverse-link-disabled-color:        #444 !default;
+$navbar-inverse-link-disabled-bg:           transparent !default;
+
+// Inverted navbar brand label
+$navbar-inverse-brand-color:                $navbar-inverse-link-color !default;
+$navbar-inverse-brand-hover-color:          #fff !default;
+$navbar-inverse-brand-hover-bg:             transparent !default;
+
+// Inverted navbar toggle
+$navbar-inverse-toggle-hover-bg:            #333 !default;
+$navbar-inverse-toggle-icon-bar-bg:         #fff !default;
+$navbar-inverse-toggle-border-color:        #333 !default;
+
+
+//== Navs
+//
+//##
+
+//=== Shared nav styles
+$nav-link-padding:                          10px 15px !default;
+$nav-link-hover-bg:                         $gray-lighter !default;
+
+$nav-disabled-link-color:                   $gray-light !default;
+$nav-disabled-link-hover-color:             $gray-light !default;
+
+//== Tabs
+$nav-tabs-border-color:                     #ddd !default;
+
+$nav-tabs-link-hover-border-color:          $gray-lighter !default;
+
+$nav-tabs-active-link-hover-bg:             $body-bg !default;
+$nav-tabs-active-link-hover-color:          $gray !default;
+$nav-tabs-active-link-hover-border-color:   #ddd !default;
+
+$nav-tabs-justified-link-border-color:            #ddd !default;
+$nav-tabs-justified-active-link-border-color:     $body-bg !default;
+
+//== Pills
+$nav-pills-border-radius:                   $border-radius-base !default;
+$nav-pills-active-link-hover-bg:            $component-active-bg !default;
+$nav-pills-active-link-hover-color:         $component-active-color !default;
+
+
+//== Pagination
+//
+//##
+
+$pagination-color:                     $link-color !default;
+$pagination-bg:                        #fff !default;
+$pagination-border:                    #ddd !default;
+
+$pagination-hover-color:               $link-hover-color !default;
+$pagination-hover-bg:                  $gray-lighter !default;
+$pagination-hover-border:              #ddd !default;
+
+$pagination-active-color:              #fff !default;
+$pagination-active-bg:                 $brand-primary !default;
+$pagination-active-border:             $brand-primary !default;
+
+$pagination-disabled-color:            $gray-light !default;
+$pagination-disabled-bg:               #fff !default;
+$pagination-disabled-border:           #ddd !default;
+
+
+//== Pager
+//
+//##
+
+$pager-bg:                             $pagination-bg !default;
+$pager-border:                         $pagination-border !default;
+$pager-border-radius:                  15px !default;
+
+$pager-hover-bg:                       $pagination-hover-bg !default;
+
+$pager-active-bg:                      $pagination-active-bg !default;
+$pager-active-color:                   $pagination-active-color !default;
+
+$pager-disabled-color:                 $pagination-disabled-color !default;
+
+
+//== Jumbotron
+//
+//##
+
+$jumbotron-padding:              30px !default;
+$jumbotron-color:                inherit !default;
+$jumbotron-bg:                   $gray-lighter !default;
+$jumbotron-heading-color:        inherit !default;
+$jumbotron-font-size:            ceil(($font-size-base * 1.5)) !default;
+$jumbotron-heading-font-size:    ceil(($font-size-base * 4.5)) !default;
+
+
+//== Form states and alerts
+//
+//## Define colors for form feedback states and, by default, alerts.
+
+$state-success-text:             #3c763d !default;
+$state-success-bg:               #dff0d8 !default;
+$state-success-border:           darken(adjust-hue($state-success-bg, -10), 5%) !default;
+
+$state-info-text:                #31708f !default;
+$state-info-bg:                  #d9edf7 !default;
+$state-info-border:              darken(adjust-hue($state-info-bg, -10), 7%) !default;
+
+$state-warning-text:             #8a6d3b !default;
+$state-warning-bg:               #fcf8e3 !default;
+$state-warning-border:           darken(adjust-hue($state-warning-bg, -10), 5%) !default;
+
+$state-danger-text:              #a94442 !default;
+$state-danger-bg:                #f2dede !default;
+$state-danger-border:            darken(adjust-hue($state-danger-bg, -10), 5%) !default;
+
+
+//== Tooltips
+//
+//##
+
+//** Tooltip max width
+$tooltip-max-width:           200px !default;
+//** Tooltip text color
+$tooltip-color:               #fff !default;
+//** Tooltip background color
+$tooltip-bg:                  #000 !default;
+$tooltip-opacity:             .9 !default;
+
+//** Tooltip arrow width
+$tooltip-arrow-width:         5px !default;
+//** Tooltip arrow color
+$tooltip-arrow-color:         $tooltip-bg !default;
+
+
+//== Popovers
+//
+//##
+
+//** Popover body background color
+$popover-bg:                          #fff !default;
+//** Popover maximum width
+$popover-max-width:                   276px !default;
+//** Popover border color
+$popover-border-color:                rgba(0,0,0,.2) !default;
+//** Popover fallback border color
+$popover-fallback-border-color:       #ccc !default;
+
+//** Popover title background color
+$popover-title-bg:                    darken($popover-bg, 3%) !default;
+
+//** Popover arrow width
+$popover-arrow-width:                 10px !default;
+//** Popover arrow color
+$popover-arrow-color:                 $popover-bg !default;
+
+//** Popover outer arrow width
+$popover-arrow-outer-width:           ($popover-arrow-width + 1) !default;
+//** Popover outer arrow color
+$popover-arrow-outer-color:           fade_in($popover-border-color, 0.05) !default;
+//** Popover outer arrow fallback color
+$popover-arrow-outer-fallback-color:  darken($popover-fallback-border-color, 20%) !default;
+
+
+//== Labels
+//
+//##
+
+//** Default label background color
+$label-default-bg:            $gray-light !default;
+//** Primary label background color
+$label-primary-bg:            $brand-primary !default;
+//** Success label background color
+$label-success-bg:            $brand-success !default;
+//** Info label background color
+$label-info-bg:               $brand-info !default;
+//** Warning label background color
+$label-warning-bg:            $brand-warning !default;
+//** Danger label background color
+$label-danger-bg:             $brand-danger !default;
+
+//** Default label text color
+$label-color:                 #fff !default;
+//** Default text color of a linked label
+$label-link-hover-color:      #fff !default;
+
+
+//== Modals
+//
+//##
+
+//** Padding applied to the modal body
+$modal-inner-padding:         15px !default;
+
+//** Padding applied to the modal title
+$modal-title-padding:         15px !default;
+//** Modal title line-height
+$modal-title-line-height:     $line-height-base !default;
+
+//** Background color of modal content area
+$modal-content-bg:                             #fff !default;
+//** Modal content border color
+$modal-content-border-color:                   rgba(0,0,0,.2) !default;
+//** Modal content border color **for IE8**
+$modal-content-fallback-border-color:          #999 !default;
+
+//** Modal backdrop background color
+$modal-backdrop-bg:           #000 !default;
+//** Modal backdrop opacity
+$modal-backdrop-opacity:      .5 !default;
+//** Modal header border color
+$modal-header-border-color:   #e5e5e5 !default;
+//** Modal footer border color
+$modal-footer-border-color:   $modal-header-border-color !default;
+
+$modal-lg:                    900px !default;
+$modal-md:                    600px !default;
+$modal-sm:                    300px !default;
+
+
+//== Alerts
+//
+//## Define alert colors, border radius, and padding.
+
+$alert-padding:               15px !default;
+$alert-border-radius:         $border-radius-base !default;
+$alert-link-font-weight:      bold !default;
+
+$alert-success-bg:            $state-success-bg !default;
+$alert-success-text:          $state-success-text !default;
+$alert-success-border:        $state-success-border !default;
+
+$alert-info-bg:               $state-info-bg !default;
+$alert-info-text:             $state-info-text !default;
+$alert-info-border:           $state-info-border !default;
+
+$alert-warning-bg:            $state-warning-bg !default;
+$alert-warning-text:          $state-warning-text !default;
+$alert-warning-border:        $state-warning-border !default;
+
+$alert-danger-bg:             $state-danger-bg !default;
+$alert-danger-text:           $state-danger-text !default;
+$alert-danger-border:         $state-danger-border !default;
+
+
+//== Progress bars
+//
+//##
+
+//** Background color of the whole progress component
+$progress-bg:                 #f5f5f5 !default;
+//** Progress bar text color
+$progress-bar-color:          #fff !default;
+//** Variable for setting rounded corners on progress bar.
+$progress-border-radius:      $border-radius-base !default;
+
+//** Default progress bar color
+$progress-bar-bg:             $brand-primary !default;
+//** Success progress bar color
+$progress-bar-success-bg:     $brand-success !default;
+//** Warning progress bar color
+$progress-bar-warning-bg:     $brand-warning !default;
+//** Danger progress bar color
+$progress-bar-danger-bg:      $brand-danger !default;
+//** Info progress bar color
+$progress-bar-info-bg:        $brand-info !default;
+
+
+//== List group
+//
+//##
+
+//** Background color on `.list-group-item`
+$list-group-bg:                 #fff !default;
+//** `.list-group-item` border color
+$list-group-border:             #ddd !default;
+//** List group border radius
+$list-group-border-radius:      $border-radius-base !default;
+
+//** Background color of single list items on hover
+$list-group-hover-bg:           #f5f5f5 !default;
+//** Text color of active list items
+$list-group-active-color:       $component-active-color !default;
+//** Background color of active list items
+$list-group-active-bg:          $component-active-bg !default;
+//** Border color of active list elements
+$list-group-active-border:      $list-group-active-bg !default;
+//** Text color for content within active list items
+$list-group-active-text-color:  lighten($list-group-active-bg, 40%) !default;
+
+//** Text color of disabled list items
+$list-group-disabled-color:      $gray-light !default;
+//** Background color of disabled list items
+$list-group-disabled-bg:         $gray-lighter !default;
+//** Text color for content within disabled list items
+$list-group-disabled-text-color: $list-group-disabled-color !default;
+
+$list-group-link-color:         #555 !default;
+$list-group-link-hover-color:   $list-group-link-color !default;
+$list-group-link-heading-color: #333 !default;
+
+
+//== Panels
+//
+//##
+
+$panel-bg:                    #fff !default;
+$panel-body-padding:          15px !default;
+$panel-heading-padding:       10px 15px !default;
+$panel-footer-padding:        $panel-heading-padding !default;
+$panel-border-radius:         $border-radius-base !default;
+
+//** Border color for elements within panels
+$panel-inner-border:          #ddd !default;
+$panel-footer-bg:             #f5f5f5 !default;
+
+$panel-default-text:          $gray-dark !default;
+$panel-default-border:        #ddd !default;
+$panel-default-heading-bg:    #f5f5f5 !default;
+
+$panel-primary-text:          #fff !default;
+$panel-primary-border:        $brand-primary !default;
+$panel-primary-heading-bg:    $brand-primary !default;
+
+$panel-success-text:          $state-success-text !default;
+$panel-success-border:        $state-success-border !default;
+$panel-success-heading-bg:    $state-success-bg !default;
+
+$panel-info-text:             $state-info-text !default;
+$panel-info-border:           $state-info-border !default;
+$panel-info-heading-bg:       $state-info-bg !default;
+
+$panel-warning-text:          $state-warning-text !default;
+$panel-warning-border:        $state-warning-border !default;
+$panel-warning-heading-bg:    $state-warning-bg !default;
+
+$panel-danger-text:           $state-danger-text !default;
+$panel-danger-border:         $state-danger-border !default;
+$panel-danger-heading-bg:     $state-danger-bg !default;
+
+
+//== Thumbnails
+//
+//##
+
+//** Padding around the thumbnail image
+$thumbnail-padding:           4px !default;
+//** Thumbnail background color
+$thumbnail-bg:                $body-bg !default;
+//** Thumbnail border color
+$thumbnail-border:            #ddd !default;
+//** Thumbnail border radius
+$thumbnail-border-radius:     $border-radius-base !default;
+
+//** Custom text color for thumbnail captions
+$thumbnail-caption-color:     $text-color !default;
+//** Padding around the thumbnail caption
+$thumbnail-caption-padding:   9px !default;
+
+
+//== Wells
+//
+//##
+
+$well-bg:                     #f5f5f5 !default;
+$well-border:                 darken($well-bg, 7%) !default;
+
+
+//== Badges
+//
+//##
+
+$badge-color:                 #fff !default;
+//** Linked badge text color on hover
+$badge-link-hover-color:      #fff !default;
+$badge-bg:                    $gray-light !default;
+
+//** Badge text color in active nav link
+$badge-active-color:          $link-color !default;
+//** Badge background color in active nav link
+$badge-active-bg:             #fff !default;
+
+$badge-font-weight:           bold !default;
+$badge-line-height:           1 !default;
+$badge-border-radius:         10px !default;
+
+
+//== Breadcrumbs
+//
+//##
+
+$breadcrumb-padding-vertical:   8px !default;
+$breadcrumb-padding-horizontal: 15px !default;
+//** Breadcrumb background color
+$breadcrumb-bg:                 #f5f5f5 !default;
+//** Breadcrumb text color
+$breadcrumb-color:              #ccc !default;
+//** Text color of current page in the breadcrumb
+$breadcrumb-active-color:       $gray-light !default;
+//** Textual separator for between breadcrumb elements
+$breadcrumb-separator:          "/" !default;
+
+
+//== Carousel
+//
+//##
+
+$carousel-text-shadow:                        0 1px 2px rgba(0,0,0,.6) !default;
+
+$carousel-control-color:                      #fff !default;
+$carousel-control-width:                      15% !default;
+$carousel-control-opacity:                    .5 !default;
+$carousel-control-font-size:                  20px !default;
+
+$carousel-indicator-active-bg:                #fff !default;
+$carousel-indicator-border-color:             #fff !default;
+
+$carousel-caption-color:                      #fff !default;
+
+
+//== Close
+//
+//##
+
+$close-font-weight:           bold !default;
+$close-color:                 #000 !default;
+$close-text-shadow:           0 1px 0 #fff !default;
+
+
+//== Code
+//
+//##
+
+$code-color:                  #c7254e !default;
+$code-bg:                     #f9f2f4 !default;
+
+$kbd-color:                   #fff !default;
+$kbd-bg:                      #333 !default;
+
+$pre-bg:                      #f5f5f5 !default;
+$pre-color:                   $gray-dark !default;
+$pre-border-color:            #ccc !default;
+$pre-scrollable-max-height:   340px !default;
+
+
+//== Type
+//
+//##
+
+//** Horizontal offset for forms and lists.
+$component-offset-horizontal: 180px !default;
+//** Text muted color
+$text-muted:                  $gray-light !default;
+//** Abbreviations and acronyms border color
+$abbr-border-color:           $gray-light !default;
+//** Headings small color
+$headings-small-color:        $gray-light !default;
+//** Blockquote small color
+$blockquote-small-color:      $gray-light !default;
+//** Blockquote font size
+$blockquote-font-size:        ($font-size-base * 1.25) !default;
+//** Blockquote border color
+$blockquote-border-color:     $gray-lighter !default;
+//** Page header border color
+$page-header-border-color:    $gray-lighter !default;
+//** Width of horizontal description list titles
+$dl-horizontal-offset:        $component-offset-horizontal !default;
+//** Point at which .dl-horizontal becomes horizontal
+$dl-horizontal-breakpoint:    $grid-float-breakpoint !default;
+//** Horizontal line color.
+$hr-border:                   $gray-lighter !default;
diff --git a/votrfront/css/_votr-bootstrap.scss b/votrfront/css/src/_votr-bootstrap.scss
similarity index 96%
rename from votrfront/css/_votr-bootstrap.scss
rename to votrfront/css/src/_votr-bootstrap.scss
index e990523..5cebc60 100644
--- a/votrfront/css/_votr-bootstrap.scss
+++ b/votrfront/css/src/_votr-bootstrap.scss
@@ -1,3 +1,4 @@
+@import "votr-variables";
 // Core variables and mixins
 @import "bootstrap/variables";
 @import "bootstrap/mixins";
@@ -27,7 +28,7 @@
 
 // Components
 //@import "bootstrap/component-animations";
-//@import "bootstrap/dropdowns";
+@import "bootstrap/dropdowns";
 @import "bootstrap/button-groups";
 //@import "bootstrap/input-groups";
 @import "bootstrap/navs";
diff --git a/votrfront/css/src/_votr-variables.scss b/votrfront/css/src/_votr-variables.scss
new file mode 100644
index 0000000..cbe1ac7
--- /dev/null
+++ b/votrfront/css/src/_votr-variables.scss
@@ -0,0 +1,18 @@
+$uniba-color: #B3231B;
+$brand-primary: $uniba-color;
+$link-color: $uniba-color;
+
+$font-size-base: 13px;
+$font-size-h4: 18px;
+$font-family-monospace: 9pt monospace;
+
+$code-color: #333;   // $text-color
+$code-bg: #F5F5F5;
+
+$nav-link-padding: 8px 13px;
+
+$navbar-inverse-bg: #535250;
+$navbar-inverse-color: #ADADAD;
+$navbar-inverse-link-color: #ADADAD;
+
+$table-condensed-cell-padding: 4px;
diff --git a/votrfront/css/main.scss b/votrfront/css/src/main.scss
similarity index 92%
rename from votrfront/css/main.scss
rename to votrfront/css/src/main.scss
index f050e8e..05ae049 100644
--- a/votrfront/css/main.scss
+++ b/votrfront/css/src/main.scss
@@ -1,25 +1,10 @@
+@import "votr-variables";
 
-$uniba-color: #B3231B;
-$brand-primary: $uniba-color;
-$link-color: $uniba-color;
+// Contain some used variables from bootstrap
+@import "mixins";
+@import "variables";
 
-$font-size-base: 13px;
-$font-size-h4: 18px;
-$font-family-monospace: 9pt monospace;
-
-$code-color: #333;   // $text-color
-$code-bg: #F5F5F5;
-
-$nav-link-padding: 8px 13px;
-
-$navbar-inverse-bg: #535250;
-$navbar-inverse-color: #ADADAD;
-$navbar-inverse-link-color: #ADADAD;
-
-$table-condensed-cell-padding: 4px;
-
-
-@import "votr-bootstrap";
+// Here continues custom SCSS
 @import "layout";
 @import "forms";
 @import "spinner";
diff --git a/votrfront/css/src/mixins/_alerts.scss b/votrfront/css/src/mixins/_alerts.scss
new file mode 100644
index 0000000..3faf0b5
--- /dev/null
+++ b/votrfront/css/src/mixins/_alerts.scss
@@ -0,0 +1,14 @@
+// Alerts
+
+@mixin alert-variant($background, $border, $text-color) {
+  background-color: $background;
+  border-color: $border;
+  color: $text-color;
+
+  hr {
+    border-top-color: darken($border, 5%);
+  }
+  .alert-link {
+    color: darken($text-color, 10%);
+  }
+}
diff --git a/votrfront/css/src/mixins/_background-variant.scss b/votrfront/css/src/mixins/_background-variant.scss
new file mode 100644
index 0000000..4c7769e
--- /dev/null
+++ b/votrfront/css/src/mixins/_background-variant.scss
@@ -0,0 +1,12 @@
+// Contextual backgrounds
+
+// [converter] $parent hack
+@mixin bg-variant($parent, $color) {
+  #{$parent} {
+    background-color: $color;
+  }
+  a#{$parent}:hover,
+  a#{$parent}:focus {
+    background-color: darken($color, 10%);
+  }
+}
diff --git a/votrfront/css/src/mixins/_border-radius.scss b/votrfront/css/src/mixins/_border-radius.scss
new file mode 100644
index 0000000..ce19499
--- /dev/null
+++ b/votrfront/css/src/mixins/_border-radius.scss
@@ -0,0 +1,18 @@
+// Single side border-radius
+
+@mixin border-top-radius($radius) {
+  border-top-right-radius: $radius;
+   border-top-left-radius: $radius;
+}
+@mixin border-right-radius($radius) {
+  border-bottom-right-radius: $radius;
+     border-top-right-radius: $radius;
+}
+@mixin border-bottom-radius($radius) {
+  border-bottom-right-radius: $radius;
+   border-bottom-left-radius: $radius;
+}
+@mixin border-left-radius($radius) {
+  border-bottom-left-radius: $radius;
+     border-top-left-radius: $radius;
+}
diff --git a/votrfront/css/src/mixins/_buttons.scss b/votrfront/css/src/mixins/_buttons.scss
new file mode 100644
index 0000000..b93f84b
--- /dev/null
+++ b/votrfront/css/src/mixins/_buttons.scss
@@ -0,0 +1,65 @@
+// Button variants
+//
+// Easily pump out default styles, as well as :hover, :focus, :active,
+// and disabled options for all buttons
+
+@mixin button-variant($color, $background, $border) {
+  color: $color;
+  background-color: $background;
+  border-color: $border;
+
+  &:focus,
+  &.focus {
+    color: $color;
+    background-color: darken($background, 10%);
+        border-color: darken($border, 25%);
+  }
+  &:hover {
+    color: $color;
+    background-color: darken($background, 10%);
+        border-color: darken($border, 12%);
+  }
+  &:active,
+  &.active,
+  .open > &.dropdown-toggle {
+    color: $color;
+    background-color: darken($background, 10%);
+        border-color: darken($border, 12%);
+
+    &:hover,
+    &:focus,
+    &.focus {
+      color: $color;
+      background-color: darken($background, 17%);
+          border-color: darken($border, 25%);
+    }
+  }
+  &:active,
+  &.active,
+  .open > &.dropdown-toggle {
+    background-image: none;
+  }
+  &.disabled,
+  &[disabled],
+  fieldset[disabled] & {
+    &:hover,
+    &:focus,
+    &.focus {
+      background-color: $background;
+          border-color: $border;
+    }
+  }
+
+  .badge {
+    color: $background;
+    background-color: $color;
+  }
+}
+
+// Button sizes
+@mixin button-size($padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) {
+  padding: $padding-vertical $padding-horizontal;
+  font-size: $font-size;
+  line-height: $line-height;
+  border-radius: $border-radius;
+}
diff --git a/votrfront/css/src/mixins/_center-block.scss b/votrfront/css/src/mixins/_center-block.scss
new file mode 100644
index 0000000..e06fb5e
--- /dev/null
+++ b/votrfront/css/src/mixins/_center-block.scss
@@ -0,0 +1,7 @@
+// Center-align a block level element
+
+@mixin center-block() {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
diff --git a/votrfront/css/src/mixins/_clearfix.scss b/votrfront/css/src/mixins/_clearfix.scss
new file mode 100644
index 0000000..dc3e2ab
--- /dev/null
+++ b/votrfront/css/src/mixins/_clearfix.scss
@@ -0,0 +1,22 @@
+// Clearfix
+//
+// For modern browsers
+// 1. The space content is one way to avoid an Opera bug when the
+//    contenteditable attribute is included anywhere else in the document.
+//    Otherwise it causes space to appear at the top and bottom of elements
+//    that are clearfixed.
+// 2. The use of `table` rather than `block` is only necessary if using
+//    `:before` to contain the top-margins of child elements.
+//
+// Source: http://nicolasgallagher.com/micro-clearfix-hack/
+
+@mixin clearfix() {
+  &:before,
+  &:after {
+    content: " "; // 1
+    display: table; // 2
+  }
+  &:after {
+    clear: both;
+  }
+}
diff --git a/votrfront/css/src/mixins/_forms.scss b/votrfront/css/src/mixins/_forms.scss
new file mode 100644
index 0000000..277aa5f
--- /dev/null
+++ b/votrfront/css/src/mixins/_forms.scss
@@ -0,0 +1,88 @@
+// Form validation states
+//
+// Used in forms.less to generate the form validation CSS for warnings, errors,
+// and successes.
+
+@mixin form-control-validation($text-color: #555, $border-color: #ccc, $background-color: #f5f5f5) {
+  // Color the label and help text
+  .help-block,
+  .control-label,
+  .radio,
+  .checkbox,
+  .radio-inline,
+  .checkbox-inline,
+  &.radio label,
+  &.checkbox label,
+  &.radio-inline label,
+  &.checkbox-inline label  {
+    color: $text-color;
+  }
+  // Set the border and box shadow on specific inputs to match
+  .form-control {
+    border-color: $border-color;
+    @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work
+    &:focus {
+      border-color: darken($border-color, 10%);
+      $shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten($border-color, 20%);
+      @include box-shadow($shadow);
+    }
+  }
+  // Set validation states also for addons
+  .input-group-addon {
+    color: $text-color;
+    border-color: $border-color;
+    background-color: $background-color;
+  }
+  // Optional feedback icon
+  .form-control-feedback {
+    color: $text-color;
+  }
+}
+
+
+// Form control focus state
+//
+// Generate a customized focus state and for any input with the specified color,
+// which defaults to the `$input-border-focus` variable.
+//
+// We highly encourage you to not customize the default value, but instead use
+// this to tweak colors on an as-needed basis. This aesthetic change is based on
+// WebKit's default styles, but applicable to a wider range of browsers. Its
+// usability and accessibility should be taken into account with any change.
+//
+// Example usage: change the default blue border and shadow to white for better
+// contrast against a dark gray background.
+@mixin form-control-focus($color: $input-border-focus) {
+  $color-rgba: rgba(red($color), green($color), blue($color), .6);
+  &:focus {
+    border-color: $color;
+    outline: 0;
+    @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px $color-rgba);
+  }
+}
+
+// Form control sizing
+//
+// Relative text size, padding, and border-radii changes for form controls. For
+// horizontal sizing, wrap controls in the predefined grid classes. `
-                {" " + type + " (" + types[type] + ")"}
-              
-            
-          )}
-        
-      
-
-      
- - - {logs.map((entry, index) => !this.state[entry.log] && - - - - - - )} - -
{(entry.time - logs[0].time).toFixed(3)}{entry.log}{entry.message}
-
- ; - } -}); - - -export var LogViewerBenchmarkContent = React.createClass({ - computeBenchmarks() { - var sums = {}; - var beginnings = {}; - - function start(what, time) { - beginnings[what] = time; - } - function end(what, time) { - if (!beginnings[what]) return; - if (!sums[what]) sums[what] = 0; - sums[what] += time - beginnings[what]; - delete beginnings[what]; - } - - logs.forEach((entry) => { - if (entry.log == 'benchmark' && entry.message.substr(0, 6) == 'Begin ') { - start(entry.message.substr(6), entry.time); - } - if (entry.log == 'benchmark' && entry.message.substr(0, 4) == 'End ') { - end(entry.message.substr(4), entry.time); - } - if (entry.log == 'rpc' && entry.message.substr(-8) == ' started') { - start('total RPC time', entry.time); - } - if (entry.log == 'rpc' && entry.message.substr(-9) == ' finished') { - end('total RPC time', entry.time); - } - }); - - return _(sums).pairs().sortBy(1).reverse().valueOf(); - }, - - render() { - var benchmarks = this.computeBenchmarks(); - - return
-
- {this.props.closeButton} - {this.props.modeButton} -
- -
- - - {benchmarks.map(([message, sum], index) => - - - - - )} - -
{sum.toFixed(3)}{message}
-
-
; - } -}); - - -export var LogViewer = React.createClass({ - toggle() { - LocalSettings.set("logViewer", - LocalSettings.get("logViewer") ? "" : "log"); - }, - - toggleMode() { - LocalSettings.set("logViewer", - LocalSettings.get("logViewer") == "log" ? "benchmark" : "log"); - }, - - handleKeypress(e) { - if (e.ctrlKey && e.altKey && e.shiftKey && e.which == 76) { // Ctrl+Alt+Shift+L - this.toggle(); - e.preventDefault(); - } - }, - - componentDidMount() { - $(window).on('keydown.logViewer', this.handleKeypress); - }, - - componentWillUnmount() { - $(window).off('keydown.logViewer'); - }, - - render() { - var mode = LocalSettings.get("logViewer"); - - if (mode != "log" && mode != "benchmark") return null; - - var modeButton = ; - - var closeButton = ; - - var C = mode == "log" ? LogViewerContent : LogViewerBenchmarkContent; - return ; - } -}); diff --git a/votrfront/js/LoginPage.js b/votrfront/js/LoginPage.js deleted file mode 100644 index 48919e1..0000000 --- a/votrfront/js/LoginPage.js +++ /dev/null @@ -1,197 +0,0 @@ - -import { AboutModal } from './About'; -import { Modal, ModalBase } from './layout'; -import { AnalyticsMixin, FakeLink } from './router'; - - -var TYPE_NAMES = { - 'cosignproxy': 'Cosign (automatické)', - 'cosignpassword': 'Cosign (meno a heslo)', - 'cosigncookie': 'Cosign (manuálne cookie)', - 'plainpassword': 'Meno a heslo', - 'demo': 'Demo' -}; - - -export var LoginForm = React.createClass({ - getInitialState() { - return { - server: Votr.settings.server || 0, - type: Votr.settings.type - }; - }, - - handleServerChange(event) { - var server = event.target.value; - var newTypes = Votr.settings.servers[server].login_types; - var type = _.includes(newTypes, this.state.type) ? this.state.type : null; - this.setState({ server, type }); - }, - - handleTypeChange(event) { - this.setState({ type: event.target.value }); - }, - - render() { - var serverConfig = Votr.settings.servers[this.state.server]; - var currentType = this.state.type || serverConfig.login_types[0]; - - return
- {Votr.settings.invalid_session && -

Vaše prihlásenie vypršalo. Prihláste sa znova.

} - - {Votr.settings.error && -
-

Prihlásenie sa nepodarilo.

-

- {"Technické detaily: "} - - {_.last(Votr.settings.error.trim("\n").split("\n"))} - - {" "} - Viac detailov... -

-

- Ak problém pretrváva, napíšte nám na fmfi-svt@googlegroups.com - . -

-
-
} - - - - {Votr.settings.servers.length > 1 ? -

- -

: - - } - - {serverConfig.login_types.length > 1 ? -

- -

: - - } - - {(currentType == 'cosignpassword' || currentType == 'plainpassword') && -
-

- -

-

- -

-
} - - {currentType == 'cosigncookie' && -
- {/* TODO: Detailed instructions for cosigncookie. */} - {serverConfig.ais_cookie && -

- -

} - {serverConfig.rest_cookie && -

- -

} -
} - - -
; - } -}); - - -export var LoginErrorModal = React.createClass({ - render() { - return -
{Votr.settings.error}
-
; - } -}); - - -export var LoginPage = React.createClass({ - mixins: [AnalyticsMixin], - - getInitialState() { - return {}; - }, - - openAbout() { - this.setState({ modal: 'about' }); - }, - - openError() { - this.setState({ modal: 'error' }); - }, - - closeModal() { - this.setState({ modal: null }); - }, - - render() { - var content =
-
-
-
- Votr -
-
-
-
-

- Votr ponúka študentom jednoduchší a pohodlnejší - spôsob, ako robiť najčastejšie činnosti zo systému AIS. Zapíšte sa na - skúšky, prezrite si vaše hodnotenia a skontrolujte si počet kreditov - bez zbytočného klikania. -

-
- -
-
- -
-
; - - var modals = { 'about': AboutModal, 'error': LoginErrorModal }; - var modalComponent = modals[this.state.modal]; - - return - {content} - - ; - } -}); diff --git a/votrfront/js/MojeHodnoteniaPage.js b/votrfront/js/MojeHodnoteniaPage.js deleted file mode 100644 index 978f259..0000000 --- a/votrfront/js/MojeHodnoteniaPage.js +++ /dev/null @@ -1,158 +0,0 @@ - -import { MojePredmetyColumns } from './MojePredmetyPage'; -import { StudiumSelector } from './StudiumSelector'; -import { CacheRequester, Loading } from './ajax'; -import { coursesStats, renderWeightedStudyAverage } from './coursesStats'; -import { classForSemester, humanizeNazovPriemeru, humanizeTerminHodnotenia, humanizeTypVyucby, plural } from './humanizeAISData'; -import { PageLayout, PageTitle } from './layout'; -import { Link } from './router'; -import { sortAs, sortTable } from './sorting'; - - -export var MojeHodnoteniaColumns = [ - ["Akademický rok", 'akademicky_rok'] -].concat(MojePredmetyColumns); -MojeHodnoteniaColumns.defaultOrder = 'a0d1a2'; - - -export var MojePriemeryColumns = [ - ["Dátum výpočtu priemeru", 'datum_vypoctu', sortAs.date], - ["Názov priemeru", 'nazov'], - ["Akademický rok", 'akademicky_rok'], - ["Semester", 'semester', null, true], - ["Získaný kredit", 'ziskany_kredit', sortAs.number], - ["Celkový počet predmetov", 'predmetov', sortAs.number], - ["Počet neabsolvovaných predmetov", 'neabsolvovanych', sortAs.number], - ["Študijný priemer", 'studijny_priemer', sortAs.number], - ["Vážený priemer", 'vazeny_priemer', sortAs.number] -]; -MojePriemeryColumns.defaultOrder = 'a0a2a1'; - - -export var MojeHodnoteniaPageContent = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired - }, - - renderHodnotenia() { - var cache = new CacheRequester(); - var {studiumKey} = this.props.query; - var [hodnotenia, message] = cache.get('get_prehlad_kreditov', studiumKey) || []; - - if (!hodnotenia) { - return ; - } - - var [hodnotenia, header] = sortTable( - hodnotenia, MojeHodnoteniaColumns, this.props.query, 'predmetySort'); - - var stats = coursesStats(hodnotenia); - - return - {header} - - {hodnotenia.map((hodnotenie) => - - - - - - - - - - - - )} - - - - - - - - - - - {message && } - -
{hodnotenie.akademicky_rok}{hodnotenie.semester} - {hodnotenie.nazov} - {hodnotenie.skratka}{hodnotenie.kredit}{humanizeTypVyucby(hodnotenie.typ_vyucby)} - {hodnotenie.hodn_znamka} - {hodnotenie.hodn_znamka ? " - " : null} - {hodnotenie.hodn_znamka_popis} - {hodnotenie.hodn_datum}{humanizeTerminHodnotenia(hodnotenie.hodn_termin)}
Celkom {stats.spolu.count} {plural(stats.spolu.count, "predmet", "predmety", "predmetov")}{stats.spolu.creditsCount}{renderWeightedStudyAverage(hodnotenia)}
{message}
; - }, - - renderPriemery() { - var cache = new CacheRequester(); - var {studiumKey} = this.props.query; - - var priemery, message; - var zapisneListy = cache.get('get_zapisne_listy', studiumKey); - - if (zapisneListy && zapisneListy.length == 0) { - priemery = []; - } else if (zapisneListy) { - var zapisnyListKey = _.max(zapisneListy, - (zapisnyList) => sortAs.date(zapisnyList.datum_zapisu)).zapisny_list_key; - [priemery, message] = cache.get('get_priemery', zapisnyListKey) || []; - } - - if (!priemery) { - return ; - } - - var [priemery, header] = sortTable( - priemery, MojePriemeryColumns, this.props.query, 'priemerySort'); - - if (!message && !priemery.length) { - message = "V AISe zatiaľ nie sú vypočítané žiadne priemery."; - } - - return - {header} - - {priemery.map((priemer, index) => - - - - - - - - - - - - )} - - {message && } -
{priemer.datum_vypoctu}{humanizeNazovPriemeru(priemer.nazov)}{priemer.akademicky_rok}{priemer.semester}{priemer.ziskany_kredit}{priemer.predmetov}{priemer.neabsolvovanych}{priemer.studijny_priemer}{priemer.vazeny_priemer}
{message}
; - }, - - render() { - return
-
- Moje hodnotenia -
- {this.renderHodnotenia()} -

Moje priemery

- {this.renderPriemery()} -
; - } -}); - - -export var MojeHodnoteniaPage = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired - }, - - render() { - return - - ; - } -}); diff --git a/votrfront/js/MojePredmetyPage.js b/votrfront/js/MojePredmetyPage.js deleted file mode 100644 index 269e51e..0000000 --- a/votrfront/js/MojePredmetyPage.js +++ /dev/null @@ -1,104 +0,0 @@ - -import { ZapisnyListSelector } from './ZapisnyListSelector'; -import { CacheRequester, Loading } from './ajax'; -import { coursesStats, renderWeightedStudyAverage } from './coursesStats'; -import { classForSemester, humanizeTerminHodnotenia, humanizeTypVyucby, plural } from './humanizeAISData'; -import { PageLayout, PageTitle } from './layout'; -import { Link } from './router'; -import { sortAs, sortTable } from './sorting'; - - -export var MojePredmetyColumns = [ - [Sem., 'semester', null, true], - ["Názov predmetu", 'nazov'], - ["Skratka predmetu", 'skratka'], - ["Kredit", 'kredit', sortAs.number], - ["Typ výučby", 'typ_vyucby'], - ["Hodnotenie", 'hodn_znamka'], - ["Dátum hodnotenia", 'hodn_datum', sortAs.date], - ["Termín hodnotenia", 'hodn_termin'] -]; -MojePredmetyColumns.defaultOrder = 'd0a1'; - - -export var MojePredmetyPageContent = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired - }, - - renderContent() { - var cache = new CacheRequester(); - var {zapisnyListKey} = this.props.query; - var [hodnotenia, message] = cache.get('get_hodnotenia', zapisnyListKey) || []; - - if (!hodnotenia) { - return ; - } - - var [hodnotenia, header] = sortTable( - hodnotenia, MojePredmetyColumns, this.props.query, 'predmetySort'); - - var stats = coursesStats(hodnotenia); - - return - {header} - - {hodnotenia.map((hodnotenie) => - - - - - - - - - - - )} - - - - - - - - - - - {message && } - -
{hodnotenie.semester} - {hodnotenie.nazov} - {hodnotenie.skratka}{hodnotenie.kredit}{humanizeTypVyucby(hodnotenie.typ_vyucby)} - {hodnotenie.hodn_znamka} - {hodnotenie.hodn_znamka ? " - " : null} - {hodnotenie.hodn_znamka_popis} - {hodnotenie.hodn_datum}{humanizeTerminHodnotenia(hodnotenie.hodn_termin)}
- Celkom {stats.spolu.count} {plural(stats.spolu.count, "predmet", "predmety", "predmetov")} - {" ("}{stats.zima.count} v zime, {stats.leto.count} v lete) - {stats.spolu.creditsCount} ({stats.zima.creditsCount}+{stats.leto.creditsCount}){renderWeightedStudyAverage(hodnotenia)}
{message}
; - }, - - render() { - var {zapisnyListKey} = this.props.query; - return
-
- Moje predmety -
- {this.renderContent()} -
; - } -}); - - -export var MojePredmetyPage = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired - }, - - render() { - return - - ; - } -}); diff --git a/votrfront/js/MojeSkuskyPage.js b/votrfront/js/MojeSkuskyPage.js deleted file mode 100644 index dd818d4..0000000 --- a/votrfront/js/MojeSkuskyPage.js +++ /dev/null @@ -1,252 +0,0 @@ - -import { ZapisnyListSelector } from './ZapisnyListSelector'; -import { CacheRequester, Loading, RequestCache, sendRpc } from './ajax'; -import { PageLayout, PageTitle } from './layout'; -import { Link } from './router'; -import { sortAs, sortTable } from './sorting'; - - -// TODO: Oddelit Aktualne terminy hodnotenia vs Stare terminy hodnotenia - -export var MojeSkuskyColumns = [ - ["Moje?", null, (termin) => !termin.datum_prihlasenia || termin.datum_odhlasenia ? 'N' : 'A'], - ["Predmet", 'nazov_predmetu'], - ["Dátum", 'datum', sortAs.date], - ["Čas", 'cas'], - ["Miestnosť", 'miestnost'], - ["Hodnotiaci", 'hodnotiaci', sortAs.personName], - ["Prihlásení", 'pocet_prihlasenych', sortAs.number], - ["Poznámka", 'poznamka'], - ["Prihlasovanie", 'prihlasovanie', sortAs.interval], - ["Odhlasovanie", 'odhlasovanie', sortAs.interval], - ["Známka", null, (termin) => termin.hodnotenie_terminu || termin.hodnotenie_predmetu] -]; - -function convertToICAL(terminy) { - // standard: https://tools.ietf.org/html/rfc5545 - // verificator: http://severinghaus.org/projects/icv/ - - // header - var lines = [ - "BEGIN:VCALENDAR", - "VERSION:2.0", - "PRODID:-//svt.fmph.uniba.sk//NONSGML votr-2017//EN", - "X-WR-CALNAME:Moje skúšky", - "X-WR-CALDESC:Kalendár skúšok vyexportovaný z aplikácie Votr", - "X-WR-TIMEZONE:Europe/Bratislava", - ]; - - var dtstamp = new Date().toISOString().replace(/[-:]/g, '').replace(/\.\d+/, ''); - - // VEVENTs - for (var termin of terminy) { - if (!termin.datum_prihlasenia || termin.datum_odhlasenia) { - // nie je prihlaseny - continue; - } - lines.push("BEGIN:VEVENT"); - - lines.push("SUMMARY:" + termin.nazov_predmetu); - - // unique identificator for each event (so we can identify copies of the same event) - var uid = termin.termin_key + "@votr.uniba.sk"; - lines.push("UID:" + uid); - - // DTSTAMP is when this VEVENT was created (exported), must be YYYYMMDDTHHMMSSZ - lines.push("DTSTAMP:" + dtstamp); - - // DTSTART, DTEND - var [den, mesiac, rok] = termin.datum.split("."); - var [hodina, minuty] = termin.cas.split(":"); - var dtstart = `${rok}${mesiac}${den}T${hodina}${minuty}00`; - - // as for there is no info about duration, we'll set it for 4 hours - var hodina_koniec = (parseInt(hodina) + 4).toString(); - // add leading zero - if (hodina_koniec.length == 1) { - hodina_koniec = "0" + hodina_koniec; - } - var dtend = `${rok}${mesiac}${den}T${hodina_koniec}${minuty}00`; - lines.push("DTSTART;TZID=Europe/Bratislava:" + dtstart); - lines.push("DTEND;TZID=Europe/Bratislava:" + dtend); - - // LOCATION - if (termin.miestnost) { - lines.push("LOCATION:" + termin.miestnost); - } - - // DESCRIPTION - //@TODO ake vsetky informacie chceme zobrazovat v popise eventu? (zatial su take, ako vo FAJR) - var desc = "Prihlasovanie: " + termin.prihlasovanie + "\n" + - "Odhlasovanie: " + termin.odhlasovanie + "\n" + - "Poznámka: " + termin.poznamka; - lines.push("DESCRIPTION:" + desc); - - lines.push("END:VEVENT"); - } - - // footer - lines.push("END:VCALENDAR"); - - return lines.map((l) => l.replace(/\n/g, "\\n")).join("\r\n"); -} - -export var MojeSkuskyPageContent = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired - }, - - renderContent() { - var cache = new CacheRequester(); - var {zapisnyListKey} = this.props.query; - - var vidim = cache.get('get_vidim_terminy_hodnotenia', zapisnyListKey); - - if (!cache.loadedAll) { - return ; - } - - if (!vidim) { - return

Skúšky pre tento zápisný list už nie sú k dispozícii.

; - } - - var terminyPrihlasene = cache.get('get_prihlasene_terminy', zapisnyListKey); - var terminyVypisane = cache.get('get_vypisane_terminy', zapisnyListKey); - - if (!terminyPrihlasene || !terminyVypisane) { - return ; - } - - var terminy = {}; - terminyVypisane.forEach((termin) => terminy[termin.termin_key] = termin); - terminyPrihlasene.forEach((termin) => terminy[termin.termin_key] = termin); - terminy = _.values(terminy); - - var [terminy, header] = sortTable( - terminy, MojeSkuskyColumns, this.props.query, 'skuskySort'); - - var message = terminy.length ? null : "Zatiaľ nie sú vypísané žiadne termíny."; - - function handleClickICal() { - var icalText = convertToICAL(terminyPrihlasene); - var blob = new Blob([icalText], {type: "text/calendar;charset=utf-8"}); - saveAs(blob, "MojeTerminy.ics", true); - } - - return
- - {header} - - {terminy.map((termin) => - - {!termin.datum_prihlasenia || termin.datum_odhlasenia ? - : - } - - - - - - - - - - - - )} - - {message && } -
{"\u2718"}{"\u2714"} - {termin.nazov_predmetu} - {termin.datum}{termin.cas}{termin.miestnost}{termin.hodnotiaci} - {termin.pocet_prihlasenych + - (termin.maximalne_prihlasenych ? "/" + termin.maximalne_prihlasenych : "")} - {termin.poznamka}{termin.prihlasovanie}{termin.odhlasovanie} - {termin.hodnotenie_terminu ? termin.hodnotenie_terminu : - termin.hodnotenie_predmetu ? termin.hodnotenie_predmetu + ' (nepriradená k termínu)' : - null} - -
{message}
- {terminy.length && } -
; - }, - - render() { - return
-
- Moje skúšky -
- {this.renderContent()} -
; - } -}); - - -export var SkuskyRegisterButton = React.createClass({ - propTypes: { - termin: React.PropTypes.object.isRequired - }, - - getInitialState() { - return { - pressed: false - }; - }, - - handleClick() { - var command = this.isSigninButton() ? 'prihlas_na_termin' : 'odhlas_z_terminu'; - var termin = this.props.termin; - - sendRpc(command, [termin.termin_key], (message) => { - if (message) { - this.setState({ pressed: false }); - alert(message); - } else { - RequestCache.invalidate('get_prihlasene_terminy'); - RequestCache.invalidate('get_vypisane_terminy'); - RequestCache.invalidate('get_prihlaseni_studenti'); - } - }); - - this.setState({ pressed: true }); - }, - - isDisabled() { - var termin = this.props.termin; - return (this.isSigninButton() && termin.moznost_prihlasit !== 'A') || this.state.pressed; - }, - - isSigninButton() { - var termin = this.props.termin; - return !termin.datum_prihlasenia || termin.datum_odhlasenia; - }, - - render() { - var termin = this.props.termin; - - if (termin.hodnotenie_terminu) { - return null; - } - - var today = new Date().toJSON().replace(/-/g, '').substring(0, 8); - if (today > sortAs.date(termin.datum)) return null; - - var buttonClass = "btn btn-xs " + (this.isSigninButton() ? "btn-success" : "btn-danger") + (this.isDisabled() ? " appear-disabled" : ""); - var buttonText = this.state.pressed ? : this.isSigninButton() ? "Prihlásiť" : "Odhlásiť"; - - return ; - } -}); - - -export var MojeSkuskyPage = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired - }, - - render() { - return - - ; - } -}); diff --git a/votrfront/js/PrehladStudiaPage.js b/votrfront/js/PrehladStudiaPage.js deleted file mode 100644 index 3473c11..0000000 --- a/votrfront/js/PrehladStudiaPage.js +++ /dev/null @@ -1,158 +0,0 @@ - -import { CacheRequester, Loading } from './ajax'; -import { PageLayout, PageTitle } from './layout'; -import { sortAs, sortTable } from './sorting'; - - -// TODO: Pridat kadejake sumarne informacie, aby to vyzeralo ako dashboard. -// TODO: Ked to raz bude rychle, pouzit to ako "home page" pri prazdnom action. -// TODO: Zvyraznit aktualne obdobia a pisat kolko casu zostava do dalsich. - - -export var PrehladStudiumColumns = [ - ["Študijný program", 'sp_popis'], - ["Rok štúdia", 'rok_studia', sortAs.number], - ["Dĺžka v semestroch", 'sp_dlzka', sortAs.number], - ["Začiatok štúdia", 'zaciatok', sortAs.date], - ["Koniec štúdia", 'koniec', sortAs.date], - ["Doplňujúce údaje", 'sp_doplnujuce_udaje'] -]; -PrehladStudiumColumns.defaultOrder = 'd4'; - - -export var PrehladZapisnyListColumns = [ - ["Akademický rok", 'akademicky_rok'], - ["Študijný program", 'sp_popis'], - ["Ročník", 'rocnik', sortAs.number], - ["Dátum zápisu", 'datum_zapisu', sortAs.date] -]; -PrehladZapisnyListColumns.defaultOrder = 'd0d3'; - - -export var PrehladStudiaPage = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired - }, - - renderObdobie(label, rpcName, arg) { - var cache = new CacheRequester(); - var result = cache.get(rpcName, arg); - return - {label} - - {result ? - result.obdobie_od + " \u2013 " + result.obdobie_do : - } - - ; - }, - - renderObdobia() { - // Obdobia predsalen neukazujeme, lebo AIS ma vacsinou zle informacie - // (skuskove je umelo predlzene kvoli moznosti zapisovat znamky, apod) a - // nechceme byt matuci. Zapnut sa daju tymto schovanym query flagom. - if (!this.props.query.reallyShowDates) { - return null; - } - - return - - {this.renderObdobie("Zimný semester", 'get_semester_obdobie', 'Z')} - {this.renderObdobie("Zimné skúškové", 'get_skuskove_obdobie', 'Z')} - {this.renderObdobie("Letný semester", 'get_semester_obdobie', 'L')} - {this.renderObdobie("Letné skúškové", 'get_skuskove_obdobie', 'L')} - -
; - }, - - renderStudia() { - var cache = new CacheRequester(); - - var studia = cache.get('get_studia'); - - if (!studia) { - return ; - } - - var [studia, header] = sortTable( - studia, PrehladStudiumColumns, this.props.query, 'studiaSort'); - - var message = studia.length ? null : "V AISe nemáte žiadne štúdiá."; - - return - {header} - - {studia.map((studium) => - - - - - - - - - )} - - {message && } -
{studium.sp_popis} ({studium.sp_skratka}){studium.rok_studia}{studium.sp_dlzka}{studium.zaciatok}{studium.koniec}{studium.sp_doplnujuce_udaje.replace(/^\((.*)\)$/, '$1')}
{message}
; - }, - - renderZapisneListy() { - var cache = new CacheRequester(); - - var studia = cache.get('get_studia'); - - if (!studia) { - return ; - } - - var zapisneListy = []; - - if (studia) studia.forEach((studium) => { - var mojeZapisneListy = cache.get('get_zapisne_listy', studium.studium_key); - if (mojeZapisneListy) mojeZapisneListy.forEach((zapisnyList) => { - zapisneListy.push(zapisnyList); - }); - }); - - var [zapisneListy, header] = sortTable( - zapisneListy, PrehladZapisnyListColumns, - this.props.query, 'zapisneListySort'); - - var showTable = zapisneListy.length || cache.loadedAll; - - var message = zapisneListy.length ? null : "V AISe nemáte žiadne zápisné listy."; - - return - {!cache.loadedAll && } - {showTable && - - {header} - - {zapisneListy.map((zapisnyList) => - - - - - - - )} - - {message && } -
{zapisnyList.akademicky_rok}{zapisnyList.sp_popis} ({zapisnyList.sp_skratka}){zapisnyList.rocnik}{zapisnyList.datum_zapisu}
{message}
} -
; - }, - - render() { - return -
- Prehľad štúdia -
- {this.renderObdobia()} -

Zoznam štúdií

- {this.renderStudia()} -

Zoznam zápisných listov

- {this.renderZapisneListy()} -
; - } -}); diff --git a/votrfront/js/PriebezneHodnoteniaPage.js b/votrfront/js/PriebezneHodnoteniaPage.js deleted file mode 100644 index 5b66718..0000000 --- a/votrfront/js/PriebezneHodnoteniaPage.js +++ /dev/null @@ -1,83 +0,0 @@ - -import { ZapisnyListSelector } from './ZapisnyListSelector'; -import { CacheRequester, Loading } from './ajax'; -import { PageLayout, PageTitle } from './layout'; -import { Link } from './router'; -import { humanizeBoolean } from './humanizeAISData'; - - -export var PriebezneHodnoteniaPageContent = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired - }, - - renderContent() { - var cache = new CacheRequester(); - var {zapisnyListKey} = this.props.query; - var [priebezneHodnotenia, message] = cache.get('get_priebezne_hodnotenia', zapisnyListKey) || []; - - if (!priebezneHodnotenia) { - return ; - } - - if (!message && !priebezneHodnotenia.length) { - message = "Tento zápisný list nemá žiadne priebežné hodnotenia."; - } - - return ( -
- {priebezneHodnotenia.map((priebHod) => -
-

- {priebHod.nazov} -

- - - - - - - - - - - - {priebHod.zaznamy.map((zaznam) => - - - - - - - - )} - -
PopisBodyZaevidovalZapočítavaťMinimum
{zaznam.dovod}{zaznam.poc_bodov} / {zaznam.maximum}{zaznam.zaevidoval}{humanizeBoolean(zaznam.zapocitavat)}{zaznam.minimum}
-
- )} - {message && {message}} -
- ); - }, - - render() { - return
-
- Priebežné hodnotenia -
- {this.renderContent()} -
; - } -}); - -export var PriebezneHodnoteniaPage = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired - }, - - render() { - return - - ; - } -}); diff --git a/votrfront/js/RegisterOsobPage.js b/votrfront/js/RegisterOsobPage.js deleted file mode 100644 index 96fa87e..0000000 --- a/votrfront/js/RegisterOsobPage.js +++ /dev/null @@ -1,210 +0,0 @@ - -import { CacheRequester, Loading } from './ajax'; -import { currentAcademicYear } from './coursesStats'; -import { FormItem, PageLayout, PageTitle } from './layout'; -import { navigate } from './router'; -import { sortAs, sortTable } from './sorting'; - - -export var RegisterOsobColumns = [ - ["Plné meno", 'plne_meno', sortAs.personName], - ["E-mail", 'email'] -]; -RegisterOsobColumns.defaultOrder = 'a0'; - -export var RegisterOsobForm = React.createClass({ - getInitialState() { - var query = this.props.query; - return { - meno: query.meno, - priezvisko: query.priezvisko, - absolventi: query.absolventi, - studenti: query.studenti, - zamestnanci: query.zamestnanci, - akademickyRok: query.akademickyRok || currentAcademicYear(), - fakulta: query.fakulta, - skratkaSp: query.skratkaSp, - uchadzaciRocnik: query.uchadzaciRocnik, - prvyRocnik: query.prvyRocnik, - druhyRocnik: query.druhyRocnik, - tretiRocnik: query.tretiRocnik, - stvrtyRocnik: query.stvrtyRocnik, - piatyRocnik: query.piatyRocnik, - siestyRocnik: query.siestyRocnik, - siedmyRocnik: query.siedmyRocnik, - osmyRocnik: query.osmyRocnik, - absolventiRocnik: query.absolventiRocnik - }; - }, - - handleFieldChange(event) { - this.setState({ [event.target.name]: event.target.value }); - }, - - handleCheckBoxChange(event) { - this.setState({ [event.target.name]: String(event.target.checked) }); - }, - - handleSubmit(event) { - event.preventDefault(); - navigate({ action: 'registerOsob', ...this.state }); - }, - - renderTextInput(label, name, focus) { - return - - ; - }, - - renderSelect(label, name, items, cache) { - return - {items ? - : } - ; - }, - - renderCheckbox(label, name) { - return ; - }, - - render() { - var cache = new CacheRequester(); - var akademickeRoky = cache.get('get_register_osob_akademicky_rok_options'); - var fakulty = cache.get('get_register_osob_fakulty'); - - return
- {this.renderTextInput("Priezvisko: ", "priezvisko", true)} - {this.renderTextInput("Meno: ", "meno", false)} - {this.renderSelect("Fakulta: ", "fakulta", fakulty, cache)} - {this.renderTextInput("Študijný program (skratka): ", "skratkaSp", false)} - {this.renderSelect("Akademický rok: ", "akademickyRok", akademickeRoky, cache)} -
-
Typ osoby:
-
- {this.renderCheckbox(" Absolventi ", "absolventi")} - {this.renderCheckbox(" Študenti ", "studenti")} - {this.renderCheckbox(" Zamestnanci ", "zamestnanci")} -
-
-
-
Rok štúdia:
-
- {this.renderCheckbox(" 1. ", 'prvyRocnik')} - {this.renderCheckbox(" 2. ", 'druhyRocnik')} - {this.renderCheckbox(" 3. ", 'tretiRocnik')} - {this.renderCheckbox(" 4. ", 'stvrtyRocnik')} - {this.renderCheckbox(" 5. ", 'piatyRocnik')} - {this.renderCheckbox(" 6. ", 'siestyRocnik')} - {this.renderCheckbox(" 7. ", 'siedmyRocnik')} - {this.renderCheckbox(" 8. ", 'osmyRocnik')} -
- {this.renderCheckbox(" Uchádzači ", 'uchadzaciRocnik')} - {this.renderCheckbox(" Absolventi ", 'absolventiRocnik')} -
-
- - - -
; - }, -}); - -export var RegisterOsobResultTable = React.createClass({ - render() { - var cache = new CacheRequester(); - var query = this.props.query; - - if(!query.akademickyRok || - !(query.meno || - query.priezvisko || - query.absolventi == "true" || - query.studenti == "true" || - query.zamestnanci == "true" || - query.fakulta || - query.skratkaSp || - query.uchadzaciRocnik == "true" || - query.prvyRocnik == "true" || - query.druhyRocnik == "true" || - query.tretiRocnik == "true" || - query.stvrtyRocnik == "true" || - query.piatyRocnik == "true" || - query.siestyRocnik == "true" || - query.siedmyRocnik == "true" || - query.osmyRocnik == "true" || - query.absolventiRocnik == "true")) { - return null; - } - - var response = cache.get('vyhladaj_osobu', - query.meno, - query.priezvisko, - query.absolventi == "true", - query.studenti == "true", - query.zamestnanci == "true", - query.akademickyRok, - query.fakulta, - query.skratkaSp, - query.uchadzaciRocnik == "true", - query.prvyRocnik == "true", - query.druhyRocnik == "true", - query.tretiRocnik == "true", - query.stvrtyRocnik == "true", - query.piatyRocnik == "true", - query.siestyRocnik == "true", - query.siedmyRocnik == "true", - query.osmyRocnik == "true", - query.absolventiRocnik == "true"); - - if (!response) { - return ; - } - - var [osoby, message] = response; - - var [osoby, header] = sortTable( - osoby, RegisterOsobColumns, this.props.query, 'osobySort'); - - if (!message && !osoby.length) { - message = "Podmienkam nevyhovuje žiadny záznam."; - } - - return
-

Výsledky

- - {header} - - {osoby.map((osoba, index) => - - - - - )} - - {message && } -
{osoba.plne_meno}{osoba.email && - {osoba.email}} -
{message}
-
; - } -}); - - -export var RegisterOsobPage = React.createClass({ - render() { - return -
- Register osôb -
- - -
; - } -}); diff --git a/votrfront/js/RegisterPredmetovPage.js b/votrfront/js/RegisterPredmetovPage.js deleted file mode 100644 index a8450c9..0000000 --- a/votrfront/js/RegisterPredmetovPage.js +++ /dev/null @@ -1,163 +0,0 @@ - -import { CacheRequester, Loading } from './ajax'; -import { currentAcademicYear } from './coursesStats'; -import { classForSemester, humanizeBoolean } from './humanizeAISData'; -import { FormItem, PageLayout, PageTitle } from './layout'; -import { Link, navigate } from './router'; -import { sortAs, sortTable } from './sorting'; - - -export var RegisterPredmetovColumns = [ - ["Názov predmetu", 'nazov'], - ["Skratka predmetu", 'skratka'], - ["Fakulta", 'fakulta'], - [Sem., 'semester'], - ["Rozsah výučby", 'rozsah_vyucby'], - ["Počet kreditov", 'kredit', sortAs.number], - ["Konanie", 'konanie'] -]; -RegisterPredmetovColumns.defaultOrder = 'a0'; - -export var RegisterPredmetovForm = React.createClass({ - getInitialState() { - var query = this.props.query; - return { - fakulta: query.fakulta, - stredisko: query.stredisko, - semester: query.semester, - stupen: query.stupen, - studijnyProgramSkratka: query.studijnyProgramSkratka, - skratkaPredmetu: query.skratkaPredmetu, - nazovPredmetu: query.nazovPredmetu, - akademickyRok: query.akademickyRok || currentAcademicYear() - }; - }, - - handleFieldChange(event) { - this.setState({ [event.target.name]: event.target.value }); - }, - - handleSubmit(event) { - event.preventDefault(); - navigate({ action: 'registerPredmetov', ...this.state }); - }, - - renderTextInput(label, name, focus) { - return - - ; - }, - - renderSelect(label, name, items, cache) { - return - {items ? - : } - ; - }, - - render() { - var cache = new CacheRequester(); - var fakulty = cache.get('get_register_predmetov_fakulta_options'); - var rocniky = cache.get('get_register_predmetov_akademicky_rok_options'); - var stupne = cache.get('get_register_predmetov_stupen_options'); - var semestre = cache.get('get_register_predmetov_semester_options'); - - return
- {this.renderTextInput("Názov predmetu: ", "nazovPredmetu", true)} - {this.renderTextInput("Skratka predmetu: ", "skratkaPredmetu", false)} - {this.renderTextInput("Študijný program (skratka): ", "studijnyProgramSkratka", false)} - {this.renderSelect("Fakulta: ", "fakulta", fakulty, cache)} - {this.renderTextInput("Stredisko: ", "stredisko", false)} - {this.renderSelect("Stupeň: ", "stupen", stupne, cache)} - {this.renderSelect("Akademický rok: ", "akademickyRok", rocniky, cache)} - {this.renderSelect("Semester: ", "semester", semestre, cache)} - - - -
; - } -}); - -export var RegisterPredmetovResultTable = React.createClass({ - render() { - var cache = new CacheRequester(); - var query = this.props.query; - if(!query.fakulta && - !query.stredisko && - !query.studijnyProgramSkratka && - !query.skratkaPredmetu && - !query.nazovPredmetu && - !query.semester && - !query.stupen) { - return null; - } - - if (!query.akademickyRok) { - return null; - } - - var response = cache.get('vyhladaj_predmety', - query.akademickyRok, - query.fakulta || null, - query.stredisko || null, - query.studijnyProgramSkratka || null, - query.skratkaPredmetu || null, - query.nazovPredmetu || null, - query.semester || null, - query.stupen || null); - - if (!response) { - return - } - - var [rows, message] = response; - - var [rows, header] = sortTable( - rows, RegisterPredmetovColumns, this.props.query, 'predmetSort'); - - if (!message && !rows.length) { - message = "Podmienkam nevyhovuje žiadny záznam."; - } - - return
-

Výsledky

- - {header} - - {rows.map((predmet) => - - - - - - - - - - )} - - {message && } -
- {predmet.nazov} - {predmet.skratka}{predmet.fakulta}{predmet.semester}{predmet.rozsah_vyucby}{predmet.kredit}{humanizeBoolean(predmet.konanie)}
{message}
-
; - } -}); - - -export var RegisterPredmetovPage = React.createClass({ - render() { - return -
- Register predmetov -
- - -
; - } -}); diff --git a/votrfront/js/StudiumSelector.js b/votrfront/js/StudiumSelector.js deleted file mode 100644 index 5a0bc63..0000000 --- a/votrfront/js/StudiumSelector.js +++ /dev/null @@ -1,68 +0,0 @@ - -import { CacheRequester, Loading } from './ajax'; -import { Link } from './router'; -import { sortAs } from './sorting'; - - -// TODO: Reduce code duplication with ZapisnyListSelector. - - -export var StudiumSelector = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired, - component: React.PropTypes.func.isRequired - }, - - getItems(cache) { - var studia = cache.get('get_studia'); - - var items = studia || []; - - return _.sortBy(items, (item) => sortAs.date(item.zaciatok)).reverse(); - }, - - renderSelector(cache, items, query) { - return
    -
  • Štúdium:
  • - {items.map((studium) => { - var key = studium.studium_key; - var active = key == query.studiumKey; - return
  • - - {studium.sp_skratka} - -
  • ; - })} - {cache.loadedAll ? null : -
  • - -
  • } -
; - }, - - renderPage(cache, items, query) { - if (query.studiumKey) { - return ; - } - if (cache.loadedAll && items.length == 0) { - return

Žiadne štúdiá.

; - } - return null; - }, - - render() { - var cache = new CacheRequester(); - var items = this.getItems(cache); - var query = this.props.query; - - if (!query.studiumKey && cache.loadedAll && items.length) { - var mostRecentItem = items[0]; - query = { ...query, studiumKey: mostRecentItem.studium_key }; - } - - return
- {this.renderSelector(cache, items, query)} - {this.renderPage(cache, items, query)} -
; - } -}); diff --git a/votrfront/js/ZapisPage.js b/votrfront/js/ZapisPage.js deleted file mode 100644 index 4b5b2a5..0000000 --- a/votrfront/js/ZapisPage.js +++ /dev/null @@ -1,577 +0,0 @@ - -import { ZapisnyListSelector } from './ZapisnyListSelector'; -import { CacheRequester, Loading, RequestCache, sendRpc } from './ajax'; -import { coursesStats } from './coursesStats'; -import { humanizeTypVyucby, plural } from './humanizeAISData'; -import { FormItem, PageLayout, PageTitle } from './layout'; -import { Link, navigate } from './router'; -import { sortAs, sortTable } from './sorting'; - - -export var ZapisZPlanuColumns = [ - ["Moje?", 'moje', null, true], - [Typ, 'typ_vyucby'], - ["Blok", null, (predmet) => parseInt(predmet.blok_index || 0) * 1000 + parseInt(predmet.v_bloku_index || 0)], - ["Názov predmetu", 'nazov'], - ["Skratka predmetu", 'skratka'], - [Sem., 'semester', null, true], - ["Rozsah výučby", 'rozsah_vyucby'], - ["Kredit", 'kredit', sortAs.number], - ["Prihlásení", 'pocet_prihlasenych', sortAs.number], - [Odp. ročník, 'odporucany_rocnik'], - ["Jazyk", 'jazyk'] -]; -ZapisZPlanuColumns.defaultOrder = 'a1a2a9a3'; - - -export var ZapisZPonukyColumns = [ - ["Moje?", 'moje', null, true], - [Typ, 'typ_vyucby'], - ["Blok", 'blok_skratka'], - ["Názov predmetu", 'nazov'], - ["Skratka predmetu", 'skratka'], - [Sem., 'semester', null, true], - ["Rozsah výučby", 'rozsah_vyucby'], - ["Kredit", 'kredit', sortAs.number], - ["Prihlásení", 'pocet_prihlasenych', sortAs.number], - ["Jazyk", 'jazyk'] -]; -ZapisZPonukyColumns.defaultOrder = 'a3'; - - -export var ZapisVlastnostiColumns = [ - ["Skratka", 'skratka'], - ["Názov", 'nazov'], - ["Minimálny kredit", 'minimalny_kredit'], - ["Poznámka", 'poznamka'] -]; - - -export var ZapisMenu = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired - }, - - renderLink(content, href, active) { - return {content}; - }, - - render() { - var {action, cast, zapisnyListKey} = this.props.query; - return
-
- Zápis predmetov -
-
- {this.renderLink("Môj študijný plán", - { action: 'zapisZPlanu', cast: 'SC', zapisnyListKey }, - action == 'zapisZPlanu' && cast != 'SS')} - {this.renderLink("Predmety štátnej skúšky", - { action: 'zapisZPlanu', cast: 'SS', zapisnyListKey }, - action == 'zapisZPlanu' && cast == 'SS')} - {this.renderLink("Hľadať ďalšie predmety", - { action: 'zapisZPonuky', zapisnyListKey }, - action == 'zapisZPonuky')} -
-
-
-
{this.props.children}
-
; - } -}); - - -export var ZapisTableFooter = React.createClass({ - propTypes: { - predmety: React.PropTypes.object.isRequired, - moje: React.PropTypes.object.isRequired - }, - - render() { - var bloky = {}, nazvy = {}, semestre = {}; - _.forEach(this.props.predmety, (predmet) => { - semestre[predmet.semestre] = true; - nazvy[predmet.blok_skratka] = predmet.blok_nazov; - }); - - _.forEach(_.sortBy(_.keys(nazvy)), (skratka) => bloky[skratka] = []); - bloky[''] = []; - - _.forEach(this.props.predmety, (predmet) => { - if (!this.props.moje[predmet.predmet_key]) return; - if (predmet.blok_skratka) bloky[predmet.blok_skratka].push(predmet); - bloky[''].push(predmet); - }); - - var jedinySemester = _.keys(semestre).length <= 1; - - return - {_.map(bloky, (blok, skratka) => { - var stats = coursesStats(blok); - return - {skratka ? "Súčet bloku" : "Dokopy"} - {nazvy[skratka] ? {skratka} : skratka} - - {stats.spolu.count} {plural(stats.spolu.count, "predmet", "predmety", "predmetov")} - {!jedinySemester && " ("+stats.zima.count+" v zime, "+stats.leto.count+" v lete)"} - - - {stats.spolu.creditsCount} - {!jedinySemester && " ("+stats.zima.creditsCount+"+"+stats.leto.creditsCount+")"} - - - ; - })} - ; - } -}); - - -export var ZapisTable = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired, - predmety: React.PropTypes.object, - akademickyRok: React.PropTypes.string, - message: React.PropTypes.node, - columns: React.PropTypes.array.isRequired, - showFooter: React.PropTypes.bool, - odoberPredmety: React.PropTypes.func.isRequired, - pridajPredmety: React.PropTypes.func.isRequired - }, - - getInitialState() { - return { odoberanePredmety: {}, pridavanePredmety: {} }; - }, - - handleChange(event) { - var predmetKey = event.target.name; - var predmet = this.props.predmety[predmetKey]; - - delete this.state.odoberanePredmety[predmetKey]; - delete this.state.pridavanePredmety[predmetKey]; - if (predmet.moje && !event.target.checked) this.state.odoberanePredmety[predmetKey] = true; - if (!predmet.moje && event.target.checked) this.state.pridavanePredmety[predmetKey] = true; - - this.forceUpdate(); - }, - - handleSave(event) { - event.preventDefault(); - - if (this.state.saving) return; - - var predmety = this.props.predmety; - - var odoberanePredmety = [], pridavanePredmety = []; - for (var predmet_key in predmety) { - if (this.state.odoberanePredmety[predmet_key] && predmety[predmet_key].moje) { - odoberanePredmety.push(predmety[predmet_key]); - } - if (this.state.pridavanePredmety[predmet_key] && !predmety[predmet_key].moje) { - pridavanePredmety.push(predmety[predmet_key]); - } - } - - this.setState({ saving: true }); - - var koniec = (odobral, pridal) => { - if (odobral) { - odoberanePredmety.forEach((predmet) => { - RequestCache['pocet_prihlasenych_je_stary' + predmet.predmet_key] = true; - }); - this.setState({ odoberanePredmety: {} }); - } - - if (pridal) { - pridavanePredmety.forEach((predmet) => { - RequestCache['pocet_prihlasenych_je_stary' + predmet.predmet_key] = true; - }); - this.setState({ pridavanePredmety: {} }); - } - - // Aj ked skoncime neuspechom, je mozne, ze niektore predmety sa zapisali. - RequestCache.invalidate('get_hodnotenia'); - RequestCache.invalidate('get_predmety'); - RequestCache.invalidate('get_prehlad_kreditov'); - RequestCache.invalidate('get_studenti_zapisani_na_predmet'); - RequestCache.invalidate('zapis_get_zapisane_predmety'); - }; - - this.props.odoberPredmety(odoberanePredmety, (message) => { - if (message) { - this.setState({ saving: false }); - alert(message); - koniec(false, false); - } else { - this.props.pridajPredmety(pridavanePredmety, (message) => { - this.setState({ saving: false }); - if (message) { - alert(message); - koniec(true, false); - } else { - koniec(true, true); - } - }); - } - }); - }, - - render() { - // Chceme, aby sa pre ZapisTable zachoval this.state aj vtedy, ked tabulku - // nevidno, lebo sme prave zapisali predmety a obnovujeme zoznam predmetov. - // Takze komponent ZapisTable sa bude renderovat vzdy, aby nikdy nezanikol - // a neprisiel o state. Niekedy proste nedostane this.props.predmety. - if (!this.props.predmety || !this.props.akademickyRok) { - return ; - } - - var {predmety, columns, query, message} = this.props; - - var classes = {}, checked = {}; - for (var predmet_key in predmety) { - checked[predmet_key] = predmety[predmet_key].moje; - if (this.state.odoberanePredmety[predmet_key] && predmety[predmet_key].moje) { - classes[predmet_key] = 'danger'; - checked[predmet_key] = false; - } - if (this.state.pridavanePredmety[predmet_key] && !predmety[predmet_key].moje) { - classes[predmet_key] = 'success'; - checked[predmet_key] = true; - } - } - - var saveButton =
- -
; - - var [predmety, header] = sortTable(_.values(predmety), columns, query, 'predmetySort'); - - return
- {saveButton} - - {header} - - {predmety.map((predmet) => { - var predmet_key = predmet.predmet_key; - var href = { ...this.props.query, modal: 'detailPredmetu', modalPredmetKey: predmet.predmet_key, modalAkademickyRok: this.props.akademickyRok }; - var nazov = {predmet.nazov}; - if (predmet.moje) nazov = {nazov}; - if (predmet.aktualnost) nazov = {nazov} (nekoná sa); - var blok = predmet.blok_skratka; - if (predmet.blok_nazov) blok = {blok}; - - return - - - - - - - - - - {columns == ZapisZPlanuColumns && } - - ; - })} - - {this.props.showFooter && } - {message && } -
- - {predmet.typ_vyucby}{blok}{nazov}{predmet.skratka}{predmet.semester}{predmet.rozsah_vyucby}{predmet.kredit}{RequestCache['pocet_prihlasenych_je_stary' + predmet_key] ? - {predmet.pocet_prihlasenych} : predmet.pocet_prihlasenych} - {predmet.maximalne_prihlasenych && "/" + predmet.maximalne_prihlasenych}{predmet.odporucany_rocnik}{predmet.jazyk.replace(/ ,/g, ', ')}
{message}
- {saveButton} -
; - } -}); - - -export var ZapisVlastnostiTable = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired - }, - - render() { - var cache = new CacheRequester(); - var {zapisnyListKey} = this.props.query; - - var [vlastnosti, message] = cache.get('zapis_get_vlastnosti_programu', zapisnyListKey) || []; - - if (!vlastnosti) { - return ; - } - - if (!message && !vlastnosti.length) { - message = "Študijný plán nemá žiadne poznámky."; - } - - var [vlastnosti, header] = sortTable( - vlastnosti, ZapisVlastnostiColumns, this.props.query, 'vlastnostiSort'); - - return - {header} - - {vlastnosti.map((vlastnost, index) => - - - - - - - )} - - {message && } -
{vlastnost.skratka}{vlastnost.nazov}{vlastnost.minimalny_kredit}{vlastnost.poznamka}
{message}
; - } -}); - - -export var ZapisZPlanuPageContent = React.createClass({ - getQuery() { - var {zapisnyListKey, cast} = this.props.query; - cast = (cast == 'SS' ? 'SS' : 'SC'); - return {zapisnyListKey, cast}; - }, - - render() { - var cache = new CacheRequester(); - var {zapisnyListKey, cast} = this.getQuery(); - - var [zapisanePredmety, zapisaneMessage] = cache.get('zapis_get_zapisane_predmety', zapisnyListKey, cast) || []; - var [ponukanePredmety, ponukaneMessage] = cache.get('zapis_plan_vyhladaj', zapisnyListKey, cast) || []; - var akademickyRok = cache.get('zapisny_list_key_to_akademicky_rok', zapisnyListKey); - - var outerMessage, tableMessage, predmety; - - if (zapisaneMessage || ponukaneMessage) { - outerMessage =

{zapisaneMessage || ponukaneMessage}

; - } else if (!cache.loadedAll) { - outerMessage = ; - } else { - var vidnoZimne = false; - - predmety = {}; - ponukanePredmety.forEach((predmet) => { - predmety[predmet.predmet_key] = { moje: false, ...predmet }; - if (predmet.semester == 'Z') vidnoZimne = true; - }); - zapisanePredmety.forEach((predmet) => { - var predmet_key = predmet.predmet_key; - if (!predmety[predmet_key]) { - if (predmet.semester == 'Z' && !vidnoZimne) return; - predmety[predmet_key] = { moje: true, ...predmet }; - } else { - for (var property in predmet) { - if (predmet[property] !== null && predmet[property] !== undefined) { - predmety[predmet_key][property] = predmet[property]; - } - } - predmety[predmet_key].moje = true; - } - }); - - if (_.isEmpty(predmety)) { - tableMessage = "Zoznam ponúkaných predmetov je prázdny."; - } - } - - return - {outerMessage} - -

Poznámky k študijnému plánu

- -
; - }, - - pridajPredmety(predmety, callback) { - if (!predmety.length) return callback(null); - - var {zapisnyListKey, cast} = this.getQuery(); - var dvojice = predmety.map((predmet) => [predmet.typ_vyucby, predmet.skratka]); - sendRpc('zapis_plan_pridaj_predmety', [zapisnyListKey, cast, dvojice], callback); - }, - - odoberPredmety(predmety, callback) { - if (!predmety.length) return callback(null); - - var {zapisnyListKey, cast} = this.getQuery(); - var kluce = predmety.map((predmet) => predmet.predmet_key); - sendRpc('zapis_odstran_predmety', [zapisnyListKey, cast, kluce], callback); - } -}); - - -export var ZapisZPlanuPage = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired - }, - - render() { - return - - ; - } -}); - - -export var ZapisZPonukyForm = React.createClass({ - getInitialState() { - var query = this.props.query; - return { - fakulta: query.fakulta, - stredisko: query.stredisko, - skratkaPredmetu: query.skratkaPredmetu, - nazovPredmetu: query.nazovPredmetu - }; - }, - - handleFieldChange(event) { - this.setState({ [event.target.name]: event.target.value }); - }, - - handleSubmit(event) { - event.preventDefault(); - var {zapisnyListKey} = this.props.query; - navigate({ action: 'zapisZPonuky', zapisnyListKey, ...this.state }); - }, - - renderTextInput(label, name, focus) { - return - - ; - }, - - renderSelect(label, name, items, cache) { - return - {items ? - : } - ; - }, - - render() { - var cache = new CacheRequester(); - var [fakulty, message] = cache.get('zapis_ponuka_options', this.props.query.zapisnyListKey) || []; - - if (!fakulty) { - return ; - } - - if (message) { - return

{message}

; - } - - return
- {this.renderTextInput("Názov predmetu: ", "nazovPredmetu", true)} - {this.renderTextInput("Skratka predmetu: ", "skratkaPredmetu", false)} - {this.renderSelect("Fakulta: ", "fakulta", fakulty, cache)} - {this.renderTextInput("Stredisko: ", "stredisko", false)} - - - -
; - } -}); - - -export var ZapisZPonukyPageContent = React.createClass({ - render() { - var cache = new CacheRequester(); - var query = this.props.query; - - var outerMessage, tableMessage, predmety, akademickyRok; - - if (query.fakulta || - query.stredisko || - query.skratkaPredmetu || - query.nazovPredmetu) { - var [zapisanePredmety, zapisaneMessage] = cache.get('zapis_get_zapisane_predmety', query.zapisnyListKey, 'SC') || []; - var [ponukanePredmety, ponukaneMessage] = cache.get('zapis_ponuka_vyhladaj', query.zapisnyListKey, - query.fakulta || null, - query.stredisko || null, - query.skratkaPredmetu || null, - query.nazovPredmetu || null) || []; - akademickyRok = cache.get('zapisny_list_key_to_akademicky_rok', query.zapisnyListKey); - - if (zapisaneMessage) { - outerMessage =

{zapisaneMessage}

; - } else if (!cache.loadedAll) { - outerMessage = ; - } else { - var predmety = {}; - ponukanePredmety.forEach((predmet) => { - predmety[predmet.predmet_key] = { moje: false, ...predmet }; - }); - zapisanePredmety.forEach((predmet) => { - if (predmety[predmet.predmet_key]) { - predmety[predmet.predmet_key].moje = true; - } - }); - - tableMessage = ponukaneMessage; - if (_.isEmpty(predmety) && !tableMessage) { - tableMessage = "Podmienkam nevyhovuje žiadny záznam."; - } - } - } - - return - - {outerMessage} - {predmety &&

Výsledky

} - -
; - }, - - pridajPredmety(predmety, callback) { - if (!predmety.length) return callback(null); - - var query = this.props.query; - var skratky = predmety.map((predmet) => predmet.skratka); - sendRpc('zapis_ponuka_pridaj_predmety', [query.zapisnyListKey, - query.fakulta || null, - query.stredisko || null, - query.skratkaPredmetu || null, - query.nazovPredmetu || null, - skratky], callback); - }, - - odoberPredmety(predmety, callback) { - if (!predmety.length) return callback(null); - - var query = this.props.query; - var kluce = predmety.map((predmet) => predmet.predmet_key); - sendRpc('zapis_odstran_predmety', [query.zapisnyListKey, 'SC', kluce], callback); - } -}); - - -export var ZapisZPonukyPage = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired - }, - - render() { - return - - ; - } -}); diff --git a/votrfront/js/ZapisnyListSelector.js b/votrfront/js/ZapisnyListSelector.js deleted file mode 100644 index 1f9c050..0000000 --- a/votrfront/js/ZapisnyListSelector.js +++ /dev/null @@ -1,70 +0,0 @@ - -import { CacheRequester, Loading } from './ajax'; -import { Link } from './router'; -import { sortAs } from './sorting'; - - -export var ZapisnyListSelector = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired, - component: React.PropTypes.func.isRequired - }, - - getItems(cache) { - var studia = cache.get('get_studia'); - - var items = []; - - if (studia) studia.forEach((studium) => { - var zapisneListy = cache.get('get_zapisne_listy', studium.studium_key); - if (zapisneListy) items.push(...zapisneListy); - }); - - return _.sortBy(items, (item) => sortAs.date(item.datum_zapisu)).reverse(); - }, - - renderSelector(cache, items, query) { - return
    -
  • Zápisný list:
  • - {items.map((zapisnyList) => { - var key = zapisnyList.zapisny_list_key; - var active = key == query.zapisnyListKey; - return
  • - - {zapisnyList.akademicky_rok} {zapisnyList.sp_skratka} - -
  • ; - })} - {cache.loadedAll ? null : -
  • - -
  • } -
; - }, - - renderPage(cache, items, query) { - if (query.zapisnyListKey) { - return ; - } - if (cache.loadedAll && items.length == 0) { - return

Žiadne zápisné listy.

; - } - return null; - }, - - render() { - var cache = new CacheRequester(); - var items = this.getItems(cache); - var query = this.props.query; - - if (!query.zapisnyListKey && cache.loadedAll && items.length) { - var mostRecentItem = items[0]; - query = { ...query, zapisnyListKey: mostRecentItem.zapisny_list_key }; - } - - return
- {this.renderSelector(cache, items, query)} - {this.renderPage(cache, items, query)} -
; - } -}); diff --git a/votrfront/js/ZoznamPrihlasenychNaTermin.js b/votrfront/js/ZoznamPrihlasenychNaTermin.js deleted file mode 100644 index 41449dc..0000000 --- a/votrfront/js/ZoznamPrihlasenychNaTermin.js +++ /dev/null @@ -1,62 +0,0 @@ - -import { CacheRequester, Loading } from './ajax'; -import { Modal } from './layout'; -import { sortAs, sortTable } from './sorting'; - - -export var ZoznamPrihlasenychNaTerminColumns = [ - ["Meno", 'plne_meno', sortAs.personName], - ["Študijný program", 'sp_skratka'], - ["Ročník", 'rocnik', sortAs.number], - ["E-mail", 'email'], - ["Dátum prihlásenia", 'datum_prihlasenia', sortAs.date] -]; - - -export var ZoznamPrihlasenychNaTerminModal = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired - }, - - renderContent() { - var cache = new CacheRequester(); - var {modalTerminKey} = this.props.query; - - if (!modalTerminKey) return null; - var studenti = cache.get('get_prihlaseni_studenti', modalTerminKey); - - if (!studenti) { - return ; - } - - var [studenti, header] = sortTable( - studenti, ZoznamPrihlasenychNaTerminColumns, - this.props.query, 'modalStudentiSort'); - - var message = studenti.length ? null : "Na termín nie sú prihlásení žiadni študenti."; - - return - {header} - - {studenti.map((student, index) => - - - - - - - - )} - - {message && } -
{student.plne_meno}{student.sp_skratka}{student.rocnik}{student.email && - {student.email}} - {student.datum_prihlasenia}
{message}
; - }, - - render() { - return - {this.renderContent()} - ; - } -}); diff --git a/votrfront/js/actions.js b/votrfront/js/actions.js deleted file mode 100644 index c2f5836..0000000 --- a/votrfront/js/actions.js +++ /dev/null @@ -1,75 +0,0 @@ - -import { AboutModal, IndexPage } from './About'; -import { DetailPredmetuModal } from './DetailPredmetu'; -import { ErrorModal } from './ErrorPage'; -import { LogViewer } from './LogViewer'; -import { MojeHodnoteniaPage } from './MojeHodnoteniaPage'; -import { PriebezneHodnoteniaPage } from './PriebezneHodnoteniaPage'; -import { MojePredmetyPage } from './MojePredmetyPage'; -import { MojeSkuskyPage } from './MojeSkuskyPage'; -import { PrehladStudiaPage } from './PrehladStudiaPage'; -import { RegisterOsobPage } from './RegisterOsobPage'; -import { RegisterPredmetovPage } from './RegisterPredmetovPage'; -import { ZapisZPlanuPage, ZapisZPonukyPage } from './ZapisPage'; -import { ZoznamPrihlasenychNaTerminModal } from './ZoznamPrihlasenychNaTermin'; -import { ModalBase, PageLayout } from './layout'; -import { navigate } from './router'; -import { AnketaPopup } from './AnketaPopup'; - - -export var NotFoundPage = React.createClass({ - render() { - return -

Action not found!

-
; - } -}); - - -export var actions = { - index: IndexPage, - priebezneHodnotenia: PriebezneHodnoteniaPage, - mojeHodnotenia: MojeHodnoteniaPage, - mojePredmety: MojePredmetyPage, - mojeSkusky: MojeSkuskyPage, - prehladStudia: PrehladStudiaPage, - registerOsob: RegisterOsobPage, - registerPredmetov: RegisterPredmetovPage, - zapisZPlanu: ZapisZPlanuPage, - zapisZPonuky: ZapisZPonukyPage -}; - - -export var modalActions = { - about: AboutModal, - detailPredmetu: DetailPredmetuModal, - zoznamPrihlasenychNaTermin: ZoznamPrihlasenychNaTerminModal -}; - - -export var App = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired - }, - - handleClose() { - if (Votr.ajaxError) return; - navigate(_.omit( - this.props.query, (value, key) => key.substring(0, 5) == 'modal')); - }, - - render() { - var query = this.props.query; - var action = query.action || 'index'; - var mainComponent = actions[action] || NotFoundPage; - var modalComponent = Votr.ajaxError ? ErrorModal : modalActions[query.modal]; - - var C = mainComponent; - return
- - - - -
; - } -}); diff --git a/votrfront/js/ajax.js b/votrfront/js/ajax.js deleted file mode 100644 index c58062d..0000000 --- a/votrfront/js/ajax.js +++ /dev/null @@ -1,143 +0,0 @@ - -export function sendRpc(name, args, callback) { - var HEADER_LENGTH = 10; - var processed = 0; - var result = undefined; - var finished = false; - - function update() { - if (finished) return; - while (true) { - var waiting = xhr.responseText.length - processed; - if (waiting < HEADER_LENGTH) break; - var header = xhr.responseText.substr(processed, HEADER_LENGTH); - var length = parseInt(header, HEADER_LENGTH); - if (waiting < HEADER_LENGTH + length) break; - var payload = xhr.responseText.substr(processed + HEADER_LENGTH, length); - var data = JSON.parse(payload); - console.log('RECEIVED', data); - if (data.log !== undefined) logs.push(data); - if (data.result !== undefined) result = data.result; - if (data.error !== undefined) return fail(data.error); - processed += HEADER_LENGTH + length; - } - if (xhr.readyState == 4) { - if (processed != xhr.responseText.length || result === undefined) { - console.log('INCOMPLETE!'); - return fail("Network error: Incomplete response"); - } - finished = true; - if (callback) { - callback(result); - } - } - Votr.appRoot.forceUpdate(); - } - - function fail(e) { - if (finished) return; - finished = true; - console.log("FAILED!", e); - if (!Votr.ajaxError) { - Votr.ajaxError = _.isString(e) ? e : "Network error"; - Votr.appRoot.forceUpdate(); - } - } - - var xhr = new XMLHttpRequest(); - xhr.onload = update; - xhr.onprogress = update; - xhr.onerror = fail; - xhr.open("POST", "rpc?name=" + name, true); - xhr.setRequestHeader("Content-Type", "application/json"); - xhr.setRequestHeader("X-CSRF-Token", Votr.settings.csrf_token); - xhr.send(JSON.stringify(args)); -} - - -Votr.ajaxError = null; - - -export var logs = []; - - -export var RequestCache = {}; - -RequestCache.pending = {}; - -RequestCache.sendRequest = function (request) { - var cacheKey = request.join('\0'); - if (RequestCache[cacheKey]) return; - if (RequestCache.pending[cacheKey]) return; - RequestCache.pending[cacheKey] = true; - sendRpc(request[0], request.slice(1), function (result) { - RequestCache[cacheKey] = result; - }); -}; - -RequestCache.invalidate = function (command) { - for (var key in RequestCache) { - if (key.split('\0')[0] === command) { - delete RequestCache[key]; - } - } - - for (var key in RequestCache.pending) { - if (key.split('\0')[0] === command) { - delete RequestCache.pending[key]; - } - } -} - - -export function CacheRequester() { - this.missing = []; - this.loadedAll = true; -}; - -CacheRequester.prototype.get = function (...request) { - var cacheKey = request.join('\0'); - if (RequestCache[cacheKey] !== undefined) { - return RequestCache[cacheKey]; - } else { - this.missing.push(request); - this.loadedAll = false; - return null; - } -}; - - -export var Loading = React.createClass({ - componentDidMount() { - if (this.props.requests) this.props.requests.forEach((request) => { - RequestCache.sendRequest(request); - }); - }, - - componentDidUpdate() { - if (this.props.requests) this.props.requests.forEach((request) => { - RequestCache.sendRequest(request); - }); - }, - - render() { - return Načítavam...; - } -}); - - -export function goPost(url) { - $('
', { method: 'POST', action: url, appendTo: 'body' }).submit(); -}; - -export function goLogout() { - goPost('logout'); -}; - -export function goReset() { - goPost('reset?destination=' + encodeURIComponent(location.search)); -}; - -export function goResetHome() { - goPost('reset?destination='); -}; diff --git a/votrfront/js/coursesStats.js b/votrfront/js/coursesStats.js deleted file mode 100644 index 8796277..0000000 --- a/votrfront/js/coursesStats.js +++ /dev/null @@ -1,71 +0,0 @@ - -var ZNAMKY = {'A': 1, 'B': 1.5, 'C': 2, 'D': 2.5, 'E': 3, 'F': 4}; - -export function coursesStats(hodnotenia) { - var result = {}; - - result.zima = {}; - result.zima.count = 0; - result.zima.creditsCount = 0; - - result.leto = {}; - result.leto.count = 0; - result.leto.creditsCount = 0; - - result.spolu = {}; - result.spolu.count = hodnotenia.length; - result.spolu.creditsCount = 0; - - hodnotenia.forEach((row) => { - var credits = parseInt(row.kredit); - if (row.hodn_znamka && row.hodn_znamka[0] === 'F') { - credits = 0; - } - result.spolu.creditsCount += credits; - if (row.semester == 'Z') { - result.zima.count += 1; - result.zima.creditsCount += credits; - } - if (row.semester == 'L') { - result.leto.count += 1; - result.leto.creditsCount += credits; - } - }); - - return result; -}; - -export function weightedStudyAverage(hodnotenia) { - var weightedSum = 0; - var creditsSum = 0; - - hodnotenia.forEach((row) => { - var value = ZNAMKY[row.hodn_znamka[0]]; - if (value) { - weightedSum += value * parseInt(row.kredit); - creditsSum += parseInt(row.kredit); - } - }); - - if (creditsSum == 0) return null; - return weightedSum / creditsSum; -}; - -export function renderWeightedStudyAverage(hodnotenia) { - var average = weightedStudyAverage(hodnotenia); - if (average === null) return null; - return {average.toFixed(2)} -}; - -export function currentAcademicYear() { - var date = new Date(); - - var year = date.getFullYear(); - var month = date.getMonth() + 1; - - if (month < 8) { - return (year - 1) + '/' + year; - } else { - return year + '/' + (year + 1); - } -}; diff --git a/votrfront/js/humanizeAISData.js b/votrfront/js/humanizeAISData.js deleted file mode 100644 index 3af7002..0000000 --- a/votrfront/js/humanizeAISData.js +++ /dev/null @@ -1,40 +0,0 @@ - -function humanizeWith(table) { - return function (value) { - return table[value] || value; - } -} - -export var humanizeTypVyucby = humanizeWith({ - 'A': 'povinné (A)', - 'B': 'povinne voliteľné (B)', - 'C': 'výberové (C)' -}); - -export var humanizeTerminHodnotenia = humanizeWith({ - 'R - Riadny termín': 'riadny', - '1 - Prvý opravný termín': 'prvý opravný', - '2 - Druhý opravný termín': 'druhý opravný' -}); - -export var humanizeNazovPriemeru = humanizeWith({ - 'Sem ?': 'Semester', - 'AkadR ?' : 'Akademický rok' -}); - -export var humanizeBoolean = humanizeWith({ - 'A': 'áno', - 'N': 'nie' -}); - -export function classForSemester(semester) { - if (semester == 'Z') return 'zima'; - if (semester == 'L') return 'leto'; - return undefined; -}; - -export function plural(count, one, few, many) { - if (count == 1) return one; - if (count >= 2 && count <= 4) return few; - return many; -}; diff --git a/votrfront/js/layout.js b/votrfront/js/layout.js deleted file mode 100644 index 96b58cf..0000000 --- a/votrfront/js/layout.js +++ /dev/null @@ -1,210 +0,0 @@ - -import { CacheRequester, Loading, goLogout, goReset, logs } from './ajax'; -import { FakeLink, Link } from './router'; - - -export var PageLayout = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired - }, - - render() { - return
- -
-
- -
-
-
- {this.props.children} -
-
-
-
; - } -}); - - -export var PageNavbar = React.createClass({ - render() { - return
-
-
- Votr -
-
- -
-
-
    -
  • O aplikácii
  • -
  • Obnoviť
  • -
  • Odhlásiť
  • -
-
-
-
; - } -}); - - -export var LogStatus = React.createClass({ - render() { - var entry = _.last(logs); - var message; - if (!entry) { - message = "\xA0"; // nbsp - } else if (entry.log == 'http' && entry.message.match(/^Requesting/)) { - message = "Čakám na AIS..."; - } else if (entry.log == 'rpc' && entry.message.match(/finished$/)) { - message = "\xA0"; // nbsp - } else { - message = "Spracovávam dáta... (" + entry.message + ")"; - } - return

{message}

; - } -}); - - -export var PageTitle = React.createClass({ - componentDidMount() { - document.title = this.refs.title.textContent; - }, - - componentDidUpdate() { - document.title = this.refs.title.textContent; - }, - - render() { - return

{this.props.children}

; - } -}); - - -export var MainMenu = React.createClass({ - propTypes: { - query: React.PropTypes.object.isRequired - }, - - renderMenuItem(content, href, moreActions) { - var isActive = href.action == this.props.query.action || (moreActions && moreActions[this.props.query.action]); - return
  • - {content} -
  • ; - }, - - renderDisabled(content) { - return
  • {content}
  • ; - }, - - render() { - var {studiumKey, zapisnyListKey} = this.props.query; - - var cache = new CacheRequester(); - var somStudent = cache.get('get_som_student'); - - return
      -
    • Moje štúdium
    • - {somStudent === false &&
    • Nie ste študentom.
    • } - {somStudent && this.renderMenuItem("Moje predmety", { action: 'mojePredmety', zapisnyListKey })} - {somStudent && this.renderMenuItem("Moje skúšky", { action: 'mojeSkusky', zapisnyListKey })} - {somStudent && this.renderMenuItem("Moje hodnotenia", { action: 'mojeHodnotenia', studiumKey })} - {somStudent && this.renderMenuItem("Priebežné hodnotenia", { action: 'priebezneHodnotenia', zapisnyListKey })} - {/*somStudent && this.renderDisabled("Môj rozvrh")*/} - {somStudent && this.renderMenuItem("Zápis predmetov", { action: 'zapisZPlanu', zapisnyListKey }, { zapisZPonuky: true })} - {somStudent && this.renderMenuItem("Prehľad štúdia", { action: 'prehladStudia' })} - {!cache.loadedAll &&
    • } -

    • -
    • Registre
    • - {this.renderMenuItem("Register osôb", { action: 'registerOsob' })} - {this.renderMenuItem("Register predmetov", { action: 'registerPredmetov' })} - {/*this.renderDisabled("Register miestností")*/} - {/*this.renderDisabled("Register študijných programov")*/} -
    ; - } -}); - - -export var FormItem = React.createClass({ - render() { - if (this.props.label) { - return ; - } else { - return
    -
    {this.props.children}
    -
    ; - } - } -}); - - -export var ModalBase = React.createClass({ - propTypes: { - component: React.PropTypes.func, - onClose: React.PropTypes.func.isRequired, - query: React.PropTypes.object.isRequired - }, - - componentDidMount() { - var $node = $(this.refs.modal); - $node.modal(); - $node.on('hide.bs.modal', (e) => { - if ($node.attr('data-show') == 'true') { - e.preventDefault(); - this.props.onClose(); - } - }); - }, - - componentDidUpdate() { - var $node = $(this.refs.modal); - $node.modal($node.attr('data-show') == 'true' ? 'show' : 'hide'); - }, - - render() { - var C = this.props.component; - - return ; - } -}); - - -export var Modal = React.createClass({ - propTypes: { - closeButton: React.PropTypes.bool.isRequired, - title: React.PropTypes.node.isRequired, - footer: React.PropTypes.node - }, - - getDefaultProps() { - return { - closeButton: true - }; - }, - - render() { - return
    -
    - {this.props.closeButton && - } -

    {this.props.title}

    -
    -
    - {this.props.children} -
    - {this.props.footer} -
    ; - } -}); diff --git a/votrfront/js/libs/modal.js b/votrfront/js/libs/modal.js new file mode 100644 index 0000000..f84142d --- /dev/null +++ b/votrfront/js/libs/modal.js @@ -0,0 +1,339 @@ +/* ======================================================================== + * Bootstrap: modal.js v3.3.7 + * http://getbootstrap.com/javascript/#modals + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // MODAL CLASS DEFINITION + // ====================== + + var Modal = function (element, options) { + this.options = options + this.$body = $(document.body) + this.$element = $(element) + this.$dialog = this.$element.find('.modal-dialog') + this.$backdrop = null + this.isShown = null + this.originalBodyPad = null + this.scrollbarWidth = 0 + this.ignoreBackdropClick = false + + if (this.options.remote) { + this.$element + .find('.modal-content') + .load(this.options.remote, $.proxy(function () { + this.$element.trigger('loaded.bs.modal') + }, this)) + } + } + + Modal.VERSION = '3.3.7' + + Modal.TRANSITION_DURATION = 300 + Modal.BACKDROP_TRANSITION_DURATION = 150 + + Modal.DEFAULTS = { + backdrop: true, + keyboard: true, + show: true + } + + Modal.prototype.toggle = function (_relatedTarget) { + return this.isShown ? this.hide() : this.show(_relatedTarget) + } + + Modal.prototype.show = function (_relatedTarget) { + var that = this + var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) + + this.$element.trigger(e) + + if (this.isShown || e.isDefaultPrevented()) return + + this.isShown = true + + this.checkScrollbar() + this.setScrollbar() + this.$body.addClass('modal-open') + + this.escape() + this.resize() + + this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) + + this.$dialog.on('mousedown.dismiss.bs.modal', function () { + that.$element.one('mouseup.dismiss.bs.modal', function (e) { + if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true + }) + }) + + this.backdrop(function () { + var transition = $.support.transition && that.$element.hasClass('fade') + + if (!that.$element.parent().length) { + that.$element.appendTo(that.$body) // don't move modals dom position + } + + that.$element + .show() + .scrollTop(0) + + that.adjustDialog() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element.addClass('in') + + that.enforceFocus() + + var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) + + transition ? + that.$dialog // wait for modal to slide in + .one('bsTransitionEnd', function () { + that.$element.trigger('focus').trigger(e) + }) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + that.$element.trigger('focus').trigger(e) + }) + } + + Modal.prototype.hide = function (e) { + if (e) e.preventDefault() + + e = $.Event('hide.bs.modal') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + + this.isShown = false + + this.escape() + this.resize() + + $(document).off('focusin.bs.modal') + + this.$element + .removeClass('in') + .off('click.dismiss.bs.modal') + .off('mouseup.dismiss.bs.modal') + + this.$dialog.off('mousedown.dismiss.bs.modal') + + $.support.transition && this.$element.hasClass('fade') ? + this.$element + .one('bsTransitionEnd', $.proxy(this.hideModal, this)) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + this.hideModal() + } + + Modal.prototype.enforceFocus = function () { + $(document) + .off('focusin.bs.modal') // guard against infinite focus loop + .on('focusin.bs.modal', $.proxy(function (e) { + if (document !== e.target && + this.$element[0] !== e.target && + !this.$element.has(e.target).length) { + this.$element.trigger('focus') + } + }, this)) + } + + Modal.prototype.escape = function () { + if (this.isShown && this.options.keyboard) { + this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { + e.which == 27 && this.hide() + }, this)) + } else if (!this.isShown) { + this.$element.off('keydown.dismiss.bs.modal') + } + } + + Modal.prototype.resize = function () { + if (this.isShown) { + $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) + } else { + $(window).off('resize.bs.modal') + } + } + + Modal.prototype.hideModal = function () { + var that = this + this.$element.hide() + this.backdrop(function () { + that.$body.removeClass('modal-open') + that.resetAdjustments() + that.resetScrollbar() + that.$element.trigger('hidden.bs.modal') + }) + } + + Modal.prototype.removeBackdrop = function () { + this.$backdrop && this.$backdrop.remove() + this.$backdrop = null + } + + Modal.prototype.backdrop = function (callback) { + var that = this + var animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $(document.createElement('div')) + .addClass('modal-backdrop ' + animate) + .appendTo(this.$body) + + this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { + if (this.ignoreBackdropClick) { + this.ignoreBackdropClick = false + return + } + if (e.target !== e.currentTarget) return + this.options.backdrop == 'static' + ? this.$element[0].focus() + : this.hide() + }, this)) + + if (doAnimate) this.$backdrop[0].offsetWidth // force reflow + + this.$backdrop.addClass('in') + + if (!callback) return + + doAnimate ? + this.$backdrop + .one('bsTransitionEnd', callback) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callback() + + } else if (!this.isShown && this.$backdrop) { + this.$backdrop.removeClass('in') + + var callbackRemove = function () { + that.removeBackdrop() + callback && callback() + } + $.support.transition && this.$element.hasClass('fade') ? + this.$backdrop + .one('bsTransitionEnd', callbackRemove) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callbackRemove() + + } else if (callback) { + callback() + } + } + + // these following methods are used to handle overflowing modals + + Modal.prototype.handleUpdate = function () { + this.adjustDialog() + } + + Modal.prototype.adjustDialog = function () { + var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight + + this.$element.css({ + paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', + paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' + }) + } + + Modal.prototype.resetAdjustments = function () { + this.$element.css({ + paddingLeft: '', + paddingRight: '' + }) + } + + Modal.prototype.checkScrollbar = function () { + var fullWindowWidth = window.innerWidth + if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 + var documentElementRect = document.documentElement.getBoundingClientRect() + fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) + } + this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth + this.scrollbarWidth = this.measureScrollbar() + } + + Modal.prototype.setScrollbar = function () { + var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) + this.originalBodyPad = document.body.style.paddingRight || '' + if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) + } + + Modal.prototype.resetScrollbar = function () { + this.$body.css('padding-right', this.originalBodyPad) + } + + Modal.prototype.measureScrollbar = function () { // thx walsh + var scrollDiv = document.createElement('div') + scrollDiv.className = 'modal-scrollbar-measure' + this.$body.append(scrollDiv) + var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth + this.$body[0].removeChild(scrollDiv) + return scrollbarWidth + } + + + // MODAL PLUGIN DEFINITION + // ======================= + + function Plugin(option, _relatedTarget) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.modal') + var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data) $this.data('bs.modal', (data = new Modal(this, options))) + if (typeof option == 'string') data[option](_relatedTarget) + else if (options.show) data.show(_relatedTarget) + }) + } + + var old = $.fn.modal + + $.fn.modal = Plugin + $.fn.modal.Constructor = Modal + + + // MODAL NO CONFLICT + // ================= + + $.fn.modal.noConflict = function () { + $.fn.modal = old + return this + } + + + // MODAL DATA-API + // ============== + + $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { + var $this = $(this) + var href = $this.attr('href') + var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 + var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) + + if ($this.is('a')) e.preventDefault() + + $target.one('show.bs.modal', function (showEvent) { + if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown + $target.one('hidden.bs.modal', function () { + $this.is(':visible') && $this.trigger('focus') + }) + }) + Plugin.call($target, option, this) + }) + +}(jQuery); diff --git a/votrfront/js/libs/transition.js b/votrfront/js/libs/transition.js new file mode 100644 index 0000000..db76596 --- /dev/null +++ b/votrfront/js/libs/transition.js @@ -0,0 +1,59 @@ +/* ======================================================================== + * Bootstrap: transition.js v3.3.7 + * http://getbootstrap.com/javascript/#transitions + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) + // ============================================================ + + function transitionEnd() { + var el = document.createElement('bootstrap') + + var transEndEventNames = { + WebkitTransition : 'webkitTransitionEnd', + MozTransition : 'transitionend', + OTransition : 'oTransitionEnd otransitionend', + transition : 'transitionend' + } + + for (var name in transEndEventNames) { + if (el.style[name] !== undefined) { + return { end: transEndEventNames[name] } + } + } + + return false // explicit for ie8 ( ._.) + } + + // http://blog.alexmaccaw.com/css-transitions + $.fn.emulateTransitionEnd = function (duration) { + var called = false + var $el = this + $(this).one('bsTransitionEnd', function () { called = true }) + var callback = function () { if (!called) $($el).trigger($.support.transition.end) } + setTimeout(callback, duration) + return this + } + + $(function () { + $.support.transition = transitionEnd() + + if (!$.support.transition) return + + $.event.special.bsTransitionEnd = { + bindType: $.support.transition.end, + delegateType: $.support.transition.end, + handle: function (e) { + if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) + } + } + }) + +}(jQuery); diff --git a/votrfront/js/main.js b/votrfront/js/main.js index 773950c..c588d5b 100644 --- a/votrfront/js/main.js +++ b/votrfront/js/main.js @@ -1,35 +1,48 @@ - -import { ErrorPage } from './ErrorPage'; -import { LoginPage } from './LoginPage'; -import { App } from './actions'; -import { Root } from './router'; - - -(function () { - -if (!history.pushState) { - return; // see prologue.js -} - -if (typeof __webpack_require__ !== 'undefined') { - Votr.webpackRequire = __webpack_require__; -} - -var query = Votr.settings.destination; -if (query !== undefined && (query == '' || query.substring(0, 1) == '?')) { - try { - history.replaceState(null, '', Votr.settings.url_root + query); - } catch (e) { - console.error(e); +import React from 'react'; +import ReactDOM from 'react-dom'; +import $ from 'jquery'; + +// TODO Remove these imports when Modals are implemented +// in our source with some package +import './libs/modal'; +import './libs/transition'; + +import { ErrorPage } from './src/ErrorPage'; +import { LoginPage } from './src/LoginPage'; +import { App } from './src/actions'; +import { Root } from './src/router'; + +// FIXME These are here just for their side effects, needs to be +// incorporated into source and deleted +import './src/prologue'; +import './src/ovce'; + +(function() { + window.$ = window.jQuery = $; + if (!history.pushState) { + // see prologue.js + return; } -} - -var root = - Votr.settings.servers ? : - Votr.settings.error ? : - ; -Votr.appRoot = ReactDOM.render(root, document.getElementById('votr')); + //if (typeof __webpack_require__ !== 'undefined') { + // Votr.webpackRequire = __webpack_require__; + //} + + const query = Votr.settings.destination; + if (query !== undefined && (query === '' || query.substring(0, 1) === '?')) { + try { + history.replaceState(null, '', Votr.settings.url_root + query); + } catch (e) { + console.error(e); + } + } + let root = ; + if (Votr.settings.servers) { + root = ; + } else if (Votr.settings.error) { + root = ; + } + Votr.appRoot = ReactDOM.render(root, document.getElementById('votr')); })(); diff --git a/votrfront/js/package.json b/votrfront/js/package.json new file mode 100644 index 0000000..c1834d9 --- /dev/null +++ b/votrfront/js/package.json @@ -0,0 +1,51 @@ +{ + "name": "votrfront", + "version": "1.0.0", + "description": "Frontend for Comenius University Votr app", + "main": "main.js", + "dependencies": { + "file-saver": "^1.3.3", + "jquery": "^1.12.4", + "lodash": "^4.17.5", + "prop-types": "^15.6.1", + "react": "^16.2.0", + "react-dom": "^16.2.0" + }, + "devDependencies": { + "@babel/core": "^7.0.0-beta.40", + "@babel/plugin-proposal-class-properties": "^7.0.0-beta.40", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.40", + "@babel/preset-env": "^7.0.0-beta.40", + "@babel/preset-react": "^7.0.0-beta.40", + "babel-eslint": "^8.2.2", + "babel-loader": "8.0.0-beta.2", + "babel-plugin-lodash": "^3.3.2", + "bootstrap-sass": "^3.3", + "clean-webpack-plugin": "^0.1.18", + "eslint": "^4.18.1", + "eslint-plugin-babel": "^4.1.2", + "eslint-plugin-import": "^2.9.0", + "eslint-plugin-react": "^7.7.0", + "lodash-webpack-plugin": "^0.11.4", + "webpack": "^4.0.1", + "webpack-bundle-analyzer": "^2.11.1", + "webpack-cli": "^2.0.9", + "webpack-merge": "^4.1.2" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "eslint": "eslint main.js src/", + "dev": "webpack -w --config webpack.dev.js", + "build": "NODE_ENV=production webpack --config webpack.prod.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/fmfi-svt/votr.git" + }, + "author": "", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/fmfi-svt/votr/issues" + }, + "homepage": "https://github.com/fmfi-svt/votr#readme" +} diff --git a/votrfront/js/sorting.js b/votrfront/js/sorting.js deleted file mode 100644 index b1ad311..0000000 --- a/votrfront/js/sorting.js +++ /dev/null @@ -1,93 +0,0 @@ - -import { navigate } from './router'; - - -export var sortAs = {}; - - -sortAs.personName = function (text) { - var words = text.replace(/,/g, '').split(' '); - words = _.filter(words, (word) => !word.match(/\.$/)); - words.unshift(words.pop()); // last name goes to the beginning - return words.join(' ').toLowerCase(); - // TODO: consider using latinise (see fajr). -}; - - -sortAs.number = function (text) { - return +text.replace(/,/g, '.'); - // TODO: this won't be needed when fladgejt starts returning numbers -}; - - -sortAs.date = function (date) { - if (date.match(/^\d\d\.\d\d\.\d\d\d\d/)) { - return date.substring(6, 10) + date.substring(3, 5) + date.substring(0, 2) + date.substring(10); - } - return date; -}; - - -sortAs.interval = function (text) { - var index = text.indexOf('do '); - if (index == -1) return ''; - return sortAs.date(text.substring(index + 3)); -}; - - -export function sortTable(items, columns, query, queryKey) { - var orderString = query[queryKey] || columns.defaultOrder; - var order = orderString ? orderString.split(/(?=[ad])/) : []; - var orderLength = order.length; - var orderAsc = order.map((orderItem) => orderItem.substring(0, 1) == 'a'); - var orderColumns = order.map((orderItem) => columns[orderItem.substring(1)]); - - items = items.map((item, index) => { - var criteria = []; - for (var i = 0; i < orderLength; i++) { - var [label, prop, process, preferDesc] = orderColumns[i]; - var value = prop ? item[prop] : item; - if (process) value = process(value); - if (!prop && !process) value = undefined; - criteria.push(value); - } - return { item, index, criteria }; - }); - - items.sort((a, b) => { - for (var i = 0; i < orderLength; i++) { - var ac = a.criteria[i], bc = b.criteria[i]; - if (ac === bc) continue; - if (ac < bc) return orderAsc[i] ? -1 : 1; - if (ac > bc) return orderAsc[i] ? 1 : -1; - } - return a.index - b.index; - }); - - items = items.map((a) => a.item); - - function handleClick(event) { - var index = event.currentTarget.getAttribute('data-index'); - var [label, prop, process, preferDesc] = columns[index]; - - var newOrder = _.without(order, 'a' + index, 'd' + index); - newOrder.unshift(( - order[0] == 'a' + index ? 'd' : - order[0] == 'd' + index ? 'a' : - preferDesc ? 'd' : 'a') + index); - - navigate({ ...query, [queryKey]: newOrder.join('') }); - } - - var header = - {columns.map(([label, prop, process, preferDesc], index) => - - {label} - - )} - ; - - return [items, header]; -}; diff --git a/votrfront/js/src/About.js b/votrfront/js/src/About.js new file mode 100644 index 0000000..ad3b6de --- /dev/null +++ b/votrfront/js/src/About.js @@ -0,0 +1,103 @@ +import React, { Component } from 'react'; +import { Modal, PageLayout } from './layout'; + +export class AboutModal extends Component { + render() { + const github = 'https://github.com/fmfi-svt/votr'; + return ( + +

    + Len málokto sa vyzná v AISe. Kým sa študent dostane k tomu, čo + potrebuje, musí sa prebiť cez hŕbu okien a menu. A ani pravidelné + činnosti, ako zapisovanie sa na skúšky, nie sú výnimkou. Preto sme + vytvorili aplikáciu Votr. Vybrali sme tie najdôležitejšie informácie z + AISu a sprístupnili sme ich na jeden klik. +

    +

    + Cez Votr si študenti môžu zapísať skúšky, pozrieť hodnotenia, + skontrolovať počet kreditov a podobne. Votr používa tie isté dáta, ako + AIS, ale podáva ich prehľadnejším spôsobom. +

    +

    Pomoc a technická podpora

    +

    + Ak vám Votr nefunguje alebo máte akékoľvek otázky, nápady či + pripomienky, napíšte nám na + fmfi-svt@googlegroups.com a radi vám pomôžeme. Alebo ak chcete, + môžete zavolať na + hotline CePIT. +

    +

    + Cez Votr sa nedá robiť všetko to, čo v AISe — sústredí sa na + zjednodušenie tých najčastejších činností. Ak hľadáte záverečné práce, + štátne skúšky a ďalšie menej časté veci, musíte ísť cez AIS. +

    +

    Autori projektu

    +

    + Votr je projektom Študentského vývojového tímu z Fakulty matematiky, + fyziky a informatiky UK. Naprogramovali ho Tomáš Belan, Dušan Plavák + a ďalší spoluautori. Vývoj prebieha + verejne na stránke {github}. Ak sa + vám Votr páči a chceli by ste sa zapojiť, napíšte nám! +

    +

    Meno projektu

    +

    + Čo znamená meno "Votr"? Je to fonetický prepis anglického slova "water". + V tejto slovnej hračke začal už predchodca Votru, ktorý sa volal "FAJR" + (pretože "fajr" a "ais" sú protiklady). Keď sme sa neskôr rozhodli + prebudovať FAJR na novom základe, nazvali sme ho "Votr", lebo má ku AISu + bližšie a vie s ním plynule narábať. Aj mená interných súčastí Votru + pokračujú v tejto téme. +

    +
    + ); + } +} +export class IndexPage extends Component { + render() { + // TODO: Use PageTitle, but show different h1. + return ( + +

    Vitajte

    +

    + Votr je alternatívne rozhranie pre systém AIS2. Cez menu sa dostanete + k týmto informáciám: +

    +
      +
    • + Moje predmety — predmety, ktoré máte zapísané + v tomto alebo minulom akademickom roku, a získané hodnotenia +

    • +
    • + Moje skúšky — termíny skúšok, na ktoré ste + prihlásení resp. na ktoré sa môžete prihlásiť +

    • +
    • + Moje hodnotenia — hodnotenia predmetov a + získané študijné priemery za celé štúdium +

    • +
    • + Priebežné hodnotenia — priebežné hodnotenia + predmetov počas semestra +

    • +
    • + Zápis predmetov — pridávanie a odoberanie + predmetov zo súčasného zápisného listu +

    • +
    • + Prehľad štúdia — zoznam vašich štúdií a + zápisných listov +

    • +
    • + Register osôb — vyhľadávanie zamestnancov, + študentov a absolventov univerzity, e-mailové kontakty +

    • +
    • + Register predmetov — vyhľadávanie predmetov, + informácie o ich učiteľoch a zoznamy zapísaných študentov +

    • +
    +
    + ); + } +} diff --git a/votrfront/js/src/AnketaPopup.js b/votrfront/js/src/AnketaPopup.js new file mode 100644 index 0000000..1561f9a --- /dev/null +++ b/votrfront/js/src/AnketaPopup.js @@ -0,0 +1,99 @@ +import React, { Component } from 'react'; +import { CacheRequester, Loading } from './ajax'; + +const dropCookie = true; // false disables the Cookie, allowing you to style the banner +const cookieDurationClose = 3; +const cookieDurationVote = 60; +const cookieName = 'anketaKolacik'; // Name of our cookie +const cookieValue = 'on'; // Value of cookie +const cookieHideDate = Date.parse('19 February 2018'); // Starting this day the cookie won't be visible + +const createCookie = (name, value, days) => { + let expires = ''; + if (days) { + const date = new Date(); + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + const expires = '; expires=' + date.toGMTString(); + } + if (dropCookie) { + document.cookie = name + '=' + value + expires + '; path=/'; + } +}; + +const checkCookie = (name) => { + const nameEQ = name + '='; + const ca = document.cookie.split(';'); + for (let i = 0; i < ca.length; i++) { + let c = ca[i]; + while (c.charAt(0) === ' ') { + c = c.substring(1, c.length); + } + if (c.indexOf(nameEQ) === 0) { + return c.substring(nameEQ.length, c.length); + }; + } + return null; +}; + +const eraseCookie = (name) => { + createCookie(name, '', -1); +}; + +export class AnketaPopup extends Component { + + componentWillMount() { + const today = new Date(); + const showPopup = (checkCookie(cookieName) !== cookieValue) && (cookieHideDate > today); + + this.setState({ showPopup }); + } + + onClosePopup(action) { + if (action === 0) { + createCookie(cookieName, cookieValue, cookieDurationVote); // Create vote cookie + } else { + createCookie(cookieName, cookieValue, cookieDurationClose); // Create close cookie + } + this.setState({ showPopup: false }); + } + + render() { + if (!this.state.showPopup) return null; + + const cache = new CacheRequester(); + const studia = cache.get('get_studia'); + if (!studia) return
    ; + if (!studia.some((s) => s.organizacna_jednotka === 'FMFI')) return null; + + return ( + + ); + } +} diff --git a/votrfront/js/src/DetailPredmetu.js b/votrfront/js/src/DetailPredmetu.js new file mode 100644 index 0000000..f7b1416 --- /dev/null +++ b/votrfront/js/src/DetailPredmetu.js @@ -0,0 +1,158 @@ +import React, { Component } from 'react'; + +import { ZoznamPrihlasenychNaTerminColumns } from './ZoznamPrihlasenychNaTermin'; +import { CacheRequester, Loading } from './ajax'; +import { Modal } from './layout'; +import { sortAs, sortTable } from './sorting'; + +export const DetailPredmetuUciteliaColumns = [ + ['Meno', 'plne_meno', sortAs.personName], + ['Typ', 'typ'], +]; +DetailPredmetuUciteliaColumns.defaultOrder = 'a0'; + +export const DetailPredmetuStudentiColumns = ZoznamPrihlasenychNaTerminColumns.slice(); +DetailPredmetuStudentiColumns.defaultOrder = 'a0'; + +export class DetailPredmetuModal extends Component { + getZapisaniStudenti = (cache, predmetKey, akademickyRok) => { + return cache.get('get_studenti_zapisani_na_predmet', predmetKey, akademickyRok); + } + + renderInformacnyListPredmetu = () => { + const cache = new CacheRequester(); + const { modalAkademickyRok, modalPredmetKey } = this.props.query; + const data = cache.get('get_informacny_list', modalPredmetKey, modalAkademickyRok); + + if (!data) { + return ; + } + + const url = 'data:application/pdf;base64,' + escape(data); + return Stiahnuť; + } + + renderUcitelia = () => { + const cache = new CacheRequester(); + const { modalAkademickyRok, modalPredmetKey } = this.props.query; + const data = this.getZapisaniStudenti(cache, modalPredmetKey, modalAkademickyRok); + + if (!data) { + return ; + } + + let [studenti, predmet] = data; + + if (!predmet) { + return 'Dáta pre predmet neboli nájdené.'; + } + + let ucitelia = cache.get( + 'get_ucitelia_predmetu', + modalPredmetKey, + modalAkademickyRok, + predmet.semester, + predmet.fakulta + ); + + if (!ucitelia) { + return ; + } + + let header; + [ucitelia, header] = sortTable( + ucitelia, DetailPredmetuUciteliaColumns, this.props.query, 'modalUciteliaSort'); + + const message = ucitelia.length ? null : 'Predmet nemá v AISe žiadnych učiteľov.'; + + return ( + + {header} + + {ucitelia.map((ucitel, index) => ( + + + + + ))} + + {message && } +
    {ucitel.plne_meno}{ucitel.typ}
    {message}
    + ); + } + + renderZapisaniStudenti = () => { + const cache = new CacheRequester(); + const { modalAkademickyRok, modalPredmetKey } = this.props.query; + + const data = this.getZapisaniStudenti(cache, modalPredmetKey, modalAkademickyRok); + + if (!data) { + return ; + } + + let [studenti, predmet] = data; + + if (!predmet) { + return 'Dáta pre predmet neboli nájdené.'; + } + + let header; + [studenti, header] = sortTable( + studenti, DetailPredmetuStudentiColumns, this.props.query, 'modalStudentiSort'); + + const message = studenti.length ? null : 'Predmet nemá v AISe žiadnych zapísaných študentov.'; + + return ( + + {header} + + {studenti.map((student, index) => ( + + + + + + + + ))} + + {message && } +
    {student.plne_meno}{student.sp_skratka}{student.rocnik}{student.email && + {student.email}} + {student.datum_prihlasenia}
    {message}
    + ); + } + + renderTitle = () => { + const cache = new CacheRequester(); + const { modalAkademickyRok, modalPredmetKey } = this.props.query; + + const data = this.getZapisaniStudenti(cache, modalPredmetKey, modalAkademickyRok); + + if (!data) { + return ; + } + + const [studenti, predmet] = data; + + if (!predmet) { + return 'Dáta nenájdené'; + } + + return predmet.nazov; + } + + render() { + return ( + +

    Informačný list predmetu

    + {this.renderInformacnyListPredmetu()} +

    Učitelia

    + {this.renderUcitelia()} +

    Zapísaní študenti

    + {this.renderZapisaniStudenti()} +
    + ); + } +} diff --git a/votrfront/js/src/ErrorPage.js b/votrfront/js/src/ErrorPage.js new file mode 100644 index 0000000..64cebb0 --- /dev/null +++ b/votrfront/js/src/ErrorPage.js @@ -0,0 +1,122 @@ +import React, { Component } from 'react'; + +import { goLogout, goReset, goResetHome } from './ajax'; +import { Modal, ModalBase } from './layout'; +import { AnalyticsMixin, FakeLink } from './router'; + +export class ErrorModal extends Component { + componentWillMount() { + this.setState({ open: false }); + } + + handleIgnore = () => { + Votr.ajaxError = null; + Votr.appRoot.forceUpdate(); + } + + handleDetails = () => { + this.setState({ open: true }); + } + + render() { + const error = Votr.settings.error || Votr.ajaxError; + const lines = error.trim('\n').split('\n'); + const lastLine = lines[lines.length - 1]; + const type = lastLine.split(':')[0]; + + let title = 'Chyba'; + let description = 'Vyskytla sa chyba a vaša požiadavka nebola spracovaná.'; + let contact = true; + + if (type === 'aisikl.exceptions.LoggedOutError') { + title = 'Prihlásenie vypršalo'; + description = 'Vaše prihlásenie vypršalo. Skúste znova.'; + contact = false; + } else if (Votr.settings.error || type.match(/^requests\.exceptions\./)) { + title = 'Chyba pripojenia'; + description = 'Votr sa nevie pripojiť na AIS.'; + contact = false; + } else { + if (type === 'aisikl.exceptions.AISParseError') { + description = 'Votr nerozumie, čo spravil AIS. V novej verzii AISu sa asi niečo zmenilo.'; + } + if (type === 'aisikl.exceptions.AISBehaviorError') { + if (lastLine.match(/args=\['(Nie je connection|Nastala SQL chyba)/)) { + description = 'AIS sa nevie pripojiť na svoju databázu.'; + contact = false; + } else { + description = 'AIS spravil niečo nečakané a Votr si s tým nevie poradiť.'; + } + } + } + + // Some errors are caused by a malformed URL, so resetting won't help. If + // we haven't navigated since the last full reload (the user has probably + // reset just now), we redirect to the front page instead. + const goHome = !Votr.didNavigate && !Votr.settings.error && location.search.substring(1); + + return ( + +

    {description}

    + {contact && +

    + Ak problém pretrváva, napíšte nám na + fmfi-svt@googlegroups.com. +

    + } +
    +
      + {goHome ? ( +
    • + +
    • + ) : ( +
    • + +
    • + )} +
    • + +
    • +
    +
    + {this.state.open + ?
    {error}
    + : ( +

    + Technické detaily: {lastLine}{' '} + Viac detailov... +

    + ) + } + {!Votr.settings.error && this.state.open && ( + + )} +
    + ); + } +} + +export class ErrorPage extends Component { + + render() { + // TODO: ModalBase should probably use transferPropsTo() instead of requiring query. + return ( + undefined} + /> + ); + } +} + +ErrorPage.mixins = [AnalyticsMixin]; diff --git a/votrfront/js/src/LocalSettings.js b/votrfront/js/src/LocalSettings.js new file mode 100644 index 0000000..86ba99f --- /dev/null +++ b/votrfront/js/src/LocalSettings.js @@ -0,0 +1,9 @@ +export const LocalSettings = { + get(key) { + return localStorage.getItem(Votr.settings.instance_name + '_' + key); + }, + set(key, value) { + localStorage.setItem(Votr.settings.instance_name + '_' + key, value); + Votr.appRoot.forceUpdate(); + }, +}; diff --git a/votrfront/js/src/LogViewer.js b/votrfront/js/src/LogViewer.js new file mode 100644 index 0000000..f4328da --- /dev/null +++ b/votrfront/js/src/LogViewer.js @@ -0,0 +1,116 @@ +import React, { Component } from 'react'; +import $ from 'jquery'; +import { LocalSettings } from './LocalSettings'; +import { logs } from './ajax'; + +export class LogViewerContent extends Component { + componentWillMount() { + this.setState({ + http: true, + table: true, + }); + } + + componentDidUpdate() { + const div = this.refs.scroll; + const time = logs[logs.length - 1].time; + if (time !== this.lastTime) { + this.lastTime = time; + div.scrollTop = div.scrollHeight; + } + } + + handleChange = (e) => { + const update = {}; + update[e.target.name] = !e.target.checked; + this.setState(update); + } + + render() { + // count the type of logs + const types = logs.reduce( + (counts, { log }) => { + counts[log] = counts[log] ? counts[log] + 1 : 1; + return counts; + }, + {} + ); + + return ( + +
      + {Object.keys(types).sort().map((type) => ( +
    • + +
    • + ))} +
    + +
    + + + {logs.map((entry, index) => !this.state[entry.log] && + + + + + + )} + +
    {(entry.time - logs[0].time).toFixed(3)}{entry.log}{entry.message}
    +
    +
    + ); + } +} + +export class LogViewer extends Component { + toggle = () => { + LocalSettings.set( + 'logViewer', + LocalSettings.get('logViewer') === 'true' ? 'false' : 'true' + ); + } + + handleKeypress = (e) => { + // Ctrl + Alt + Shift + L + if (e.ctrlKey && e.altKey && e.shiftKey && e.which === 76) { + this.toggle(); + e.preventDefault(); + } + } + + componentDidMount() { + $(window).on('keypress.logViewer', this.handleKeypress); + } + + componentWillUnmount() { + $(window).off('keypress.logViewer'); + } + + render() { + if (LocalSettings.get('logViewer') !== 'true') { + return null; + } + + return ( +
    + +
    + +
    +
    + ); + } +} diff --git a/votrfront/js/src/LoginPage.js b/votrfront/js/src/LoginPage.js new file mode 100644 index 0000000..eb6fa63 --- /dev/null +++ b/votrfront/js/src/LoginPage.js @@ -0,0 +1,209 @@ +import React, { Component } from 'react'; + +import { AboutModal } from './About'; +import { Modal, ModalBase } from './layout'; +import { AnalyticsMixin, FakeLink } from './router'; + +const TYPE_NAMES = { + cosignproxy: 'Cosign (automatické)', + cosignpassword: 'Cosign (meno a heslo)', + cosigncookie: 'Cosign (manuálne cookie)', + plainpassword: 'Meno a heslo', + demo: 'Demo', +}; + +export class LoginForm extends Component { + componentWillMount() { + this.setState({ + server: Votr.settings.server || 0, + type: Votr.settings.type, + }); + } + + handleServerChange = (event) => { + const server = event.target.value; + const newTypes = Votr.settings.servers[server].login_types; + const type = newTypes.indexOf(this.state.type) > -1 ? this.state.type : null; + this.setState({ server, type }); + } + + handleTypeChange = (event) => { + this.setState({ type: event.target.value }); + } + + render() { + const serverConfig = Votr.settings.servers[this.state.server]; + const currentType = this.state.type || serverConfig.login_types[0]; + let error; + if (Votr.settings.error) { + const errors = Votr.settings.error.trim('\n').split('\n'); + error = errors[errors.length - 1]; + } + return ( + + {Votr.settings.invalid_session && +

    Vaše prihlásenie vypršalo. Prihláste sa znova.

    } + + {error && ( +
    +

    Prihlásenie sa nepodarilo.

    +

    + {'Technické detaily: '} + + {error} + + {' '} + Viac detailov... +

    +

    + Ak problém pretrváva, napíšte nám na + + fmfi-svt@googlegroups.com + . +

    +
    +
    + )} + + + + {Votr.settings.servers.length > 1 ? +

    + +

    : + + } + + {serverConfig.login_types.length > 1 ? +

    + +

    : + + } + + {(currentType === 'cosignpassword' || currentType === 'plainpassword') && +
    +

    + +

    +

    + +

    +
    } + + {currentType === 'cosigncookie' && +
    + {/* TODO: Detailed instructions for cosigncookie. */} + {serverConfig.ais_cookie && +

    + +

    } + {serverConfig.rest_cookie && +

    + +

    } +
    } + + + + ); + } +} + +export class LoginErrorModal extends Component { + render() { + return ( + +
    {Votr.settings.error}
    +
    + ); + } +} + +export class LoginPage extends Component { + + componentWillMount() { + this.setState({ modal: null }); + } + + openAbout = () => { + this.setState({ modal: 'about' }); + } + + openError = () => { + this.setState({ modal: 'error' }); + } + + closeModal = () => { + this.setState({ modal: null }); + } + + render() { + const content = ( +
    +
    +
    +
    + Votr +
    +
    +
    +
    +

    + Votr ponúka študentom jednoduchší a pohodlnejší + spôsob, ako robiť najčastejšie činnosti zo systému AIS. Zapíšte sa na + skúšky, prezrite si vaše hodnotenia a skontrolujte si počet kreditov + bez zbytočného klikania. +

    +
    + +
    +
    + +
    +
    + ); + + const modals = { about: AboutModal, error: LoginErrorModal }; + const modalComponent = modals[this.state.modal]; + + return ( + + {content} + + + ); + } +} + +LoginPage.mixins = [AnalyticsMixin]; diff --git a/votrfront/js/src/MojeHodnoteniaPage.js b/votrfront/js/src/MojeHodnoteniaPage.js new file mode 100644 index 0000000..6ad1c80 --- /dev/null +++ b/votrfront/js/src/MojeHodnoteniaPage.js @@ -0,0 +1,193 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +import { MojePredmetyColumns } from './MojePredmetyPage'; +import { StudiumSelector } from './StudiumSelector'; +import { CacheRequester, Loading } from './ajax'; +import { coursesStats, renderWeightedStudyAverage } from './coursesStats'; +import { + classForSemester, humanizeNazovPriemeru, humanizeTerminHodnotenia, humanizeTypVyucby, + plural, +} from './humanizeAISData'; +import { PageLayout, PageTitle } from './layout'; +import { Link } from './router'; +import { sortAs, sortTable } from './sorting'; + + +export const MojeHodnoteniaColumns = [ + [ + 'Akademický rok', + 'akademicky_rok', + ], +].concat(MojePredmetyColumns); +MojeHodnoteniaColumns.defaultOrder = 'a0d1a2'; + + +export const MojePriemeryColumns = [ + ['Dátum výpočtu priemeru', 'datum_vypoctu', sortAs.date], + ['Názov priemeru', 'nazov'], + ['Akademický rok', 'akademicky_rok'], + ['Semester', 'semester', null, true], + ['Získaný kredit', 'ziskany_kredit', sortAs.number], + ['Celkový počet predmetov', 'predmetov', sortAs.number], + ['Počet neabsolvovaných predmetov', 'neabsolvovanych', sortAs.number], + ['Študijný priemer', 'studijny_priemer', sortAs.number], + ['Vážený priemer', 'vazeny_priemer', sortAs.number], +]; +MojePriemeryColumns.defaultOrder = 'a0a2a1'; + +export class MojeHodnoteniaPageContent extends Component { + + renderHodnotenia = () => { + const cache = new CacheRequester(); + const { studiumKey } = this.props.query; + let [hodnotenia, message] = cache.get('get_prehlad_kreditov', studiumKey) || []; + + if (!hodnotenia) { + return ; + } + + let header; + [hodnotenia, header] = sortTable( + hodnotenia, MojeHodnoteniaColumns, this.props.query, 'predmetySort'); + + const stats = coursesStats(hodnotenia); + + return ( + + {header} + + {hodnotenia.map((hodnotenie) => ( + + + + + + + + + + + + ))} + + + + + + + + {message && } + +
    {hodnotenie.akademicky_rok}{hodnotenie.semester} + + {hodnotenie.nazov} + + {hodnotenie.skratka}{hodnotenie.kredit}{humanizeTypVyucby(hodnotenie.typ_vyucby)} + {hodnotenie.hodn_znamka} + {hodnotenie.hodn_znamka ? ' - ' : null} + {hodnotenie.hodn_znamka_popis} + {hodnotenie.hodn_datum}{humanizeTerminHodnotenia(hodnotenie.hodn_termin)}
    + Celkom {stats.spolu.count} {plural(stats.spolu.count, 'predmet', 'predmety', 'predmetov')} + {stats.spolu.creditsCount} + {renderWeightedStudyAverage(hodnotenia)} + +
    {message}
    + ); + } + + renderPriemery = () => { + const cache = new CacheRequester(); + const { studiumKey } = this.props.query; + + let priemery, message; + const zapisneListy = cache.get('get_zapisne_listy', studiumKey); + + if (zapisneListy && zapisneListy.length === 0) { + priemery = []; + } else if (zapisneListy) { + // Find the newest list + let zapisnyList = zapisneListy[0]; + + zapisneListy.forEach((list) => { + if (sortAs.date(list.datum_zapisu) > sortAs.date(zapisnyList.datum_zapisu)) { + zapisnyList = list; + } + }); + const zapisnyListKey = zapisnyList.zapisny_list_key; + [priemery, message] = cache.get('get_priemery', zapisnyListKey) || []; + } + + if (!priemery) { + return ; + } + + let header; + [priemery, header] = sortTable( + priemery, MojePriemeryColumns, this.props.query, 'priemerySort'); + + if (!message && !priemery.length) { + message = 'V AISe zatiaľ nie sú vypočítané žiadne priemery.'; + } + + return ( + + {header} + + {priemery.map((priemer, index) => ( + + + + + + + + + + + + ))} + + {message && } +
    {priemer.datum_vypoctu}{humanizeNazovPriemeru(priemer.nazov)}{priemer.akademicky_rok}{priemer.semester}{priemer.ziskany_kredit}{priemer.predmetov}{priemer.neabsolvovanych}{priemer.studijny_priemer}{priemer.vazeny_priemer}
    {message}
    + ); + } + + render() { + return ( +
    +
    + Moje hodnotenia +
    + {this.renderHodnotenia()} +

    Moje priemery

    + {this.renderPriemery()} +
    + ); + } +} + +MojeHodnoteniaPageContent.propTypes = { + query: PropTypes.object.isRequired, +}; + +export class MojeHodnoteniaPage extends Component { + render() { + return ( + + + + ); + } +} + +MojeHodnoteniaPage.propTypes = { + query: PropTypes.object.isRequired, +}; diff --git a/votrfront/js/src/MojePredmetyPage.js b/votrfront/js/src/MojePredmetyPage.js new file mode 100644 index 0000000..8dc0a6b --- /dev/null +++ b/votrfront/js/src/MojePredmetyPage.js @@ -0,0 +1,121 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +import { ZapisnyListSelector } from './ZapisnyListSelector'; +import { CacheRequester, Loading } from './ajax'; +import { coursesStats, renderWeightedStudyAverage } from './coursesStats'; +import { classForSemester, humanizeTerminHodnotenia, humanizeTypVyucby, plural } from './humanizeAISData'; +import { PageLayout, PageTitle } from './layout'; +import { Link } from './router'; +import { sortAs, sortTable } from './sorting'; + + +export const MojePredmetyColumns = [ + [Sem., 'semester', null, true], + ['Názov predmetu', 'nazov'], + ['Skratka predmetu', 'skratka'], + ['Kredit', 'kredit', sortAs.number], + ['Typ výučby', 'typ_vyucby'], + ['Hodnotenie', 'hodn_znamka'], + ['Dátum hodnotenia', 'hodn_datum', sortAs.date], + ['Termín hodnotenia', 'hodn_termin'], +]; +MojePredmetyColumns.defaultOrder = 'd0a1'; + +export class MojePredmetyPageContent extends Component { + + renderContent = () => { + const cache = new CacheRequester(); + const { zapisnyListKey } = this.props.query; + let [hodnotenia, message] = cache.get('get_hodnotenia', zapisnyListKey) || []; + + if (!hodnotenia) { + return ; + } + + let header; + [hodnotenia, header] = sortTable( + hodnotenia, MojePredmetyColumns, this.props.query, 'predmetySort'); + + const stats = coursesStats(hodnotenia); + + return ( + + {header} + + {hodnotenia.map((hodnotenie) => ( + + + + + + + + + + + ))} + + + + + + + + {message && } + +
    {hodnotenie.semester} + + {hodnotenie.nazov} + + {hodnotenie.skratka}{hodnotenie.kredit}{humanizeTypVyucby(hodnotenie.typ_vyucby)} + {hodnotenie.hodn_znamka} + {hodnotenie.hodn_znamka ? ' - ' : null} + {hodnotenie.hodn_znamka_popis} + {hodnotenie.hodn_datum}{humanizeTerminHodnotenia(hodnotenie.hodn_termin)}
    + Celkom {stats.spolu.count} {plural(stats.spolu.count, 'predmet', 'predmety', 'predmetov')} + {' ('}{stats.zima.count} v zime, {stats.leto.count} v lete) + {stats.spolu.creditsCount} ({stats.zima.creditsCount}+{stats.leto.creditsCount}) + {renderWeightedStudyAverage(hodnotenia)} + +
    {message}
    + ); + } + + render() { + return ( +
    +
    + Moje predmety +
    + {this.renderContent()} +
    + ); + } +} + +MojePredmetyPageContent.propTypes = { + query: PropTypes.object.isRequired, +}; + +export class MojePredmetyPage extends Component { + + render() { + return ( + + + + ); + } +} + +MojePredmetyPage.propTypes = { + query: PropTypes.object.isRequired, +}; diff --git a/votrfront/js/src/MojeSkuskyPage.js b/votrfront/js/src/MojeSkuskyPage.js new file mode 100644 index 0000000..7a491b1 --- /dev/null +++ b/votrfront/js/src/MojeSkuskyPage.js @@ -0,0 +1,306 @@ +import React, { Component } from 'react'; +import FileSaver from 'file-saver'; +import PropTypes from 'prop-types'; + +import { ZapisnyListSelector } from './ZapisnyListSelector'; +import { CacheRequester, Loading, RequestCache, sendRpc } from './ajax'; +import { PageLayout, PageTitle } from './layout'; +import { Link } from './router'; +import { sortAs, sortTable } from './sorting'; + + +// TODO: Oddelit Aktualne terminy hodnotenia vs Stare terminy hodnotenia + +export const MojeSkuskyColumns = [ + ['Moje?', null, (termin) => !termin.datum_prihlasenia || termin.datum_odhlasenia ? 'N' : 'A'], + ['Predmet', 'nazov_predmetu'], + ['Dátum', 'datum', sortAs.date], + ['Čas', 'cas'], + ['Miestnosť', 'miestnost'], + ['Hodnotiaci', 'hodnotiaci', sortAs.personName], + ['Prihlásení', 'pocet_prihlasenych', sortAs.number], + ['Poznámka', 'poznamka'], + ['Prihlasovanie', 'prihlasovanie', sortAs.interval], + ['Odhlasovanie', 'odhlasovanie', sortAs.interval], + ['Známka', null, (termin) => termin.hodnotenie_terminu || termin.hodnotenie_predmetu], +]; + +const convertToICAL = (terminy) => { + // standard: https://tools.ietf.org/html/rfc5545 + // verificator: http://severinghaus.org/projects/icv/ + + // header + const lines = [ + 'BEGIN:VCALENDAR', + 'VERSION:2.0', + 'PRODID:-//svt.fmph.uniba.sk//NONSGML votr-2017//EN', + 'X-WR-CALNAME:Moje skúšky', + 'X-WR-CALDESC:Kalendár skúšok vyexportovaný z aplikácie Votr', + 'X-WR-TIMEZONE:Europe/Bratislava', + ]; + + const dtstamp = new Date().toISOString().replace(/[-:]/g, '').replace(/\.\d+/, ''); + + // VEVENTs + for (let termin of terminy) { + if (!termin.datum_prihlasenia || termin.datum_odhlasenia) { + // nie je prihlaseny + continue; + } + lines.push('BEGIN:VEVENT'); + + lines.push('SUMMARY:' + termin.nazov_predmetu); + + // unique identificator for each event (so we can identify copies of the same event) + const uid = termin.termin_key + '@votr.uniba.sk'; + lines.push('UID:' + uid); + + // DTSTAMP is when this VEVENT was created (exported), must be YYYYMMDDTHHMMSSZ + lines.push('DTSTAMP:' + dtstamp); + + // DTSTART, DTEND + const [den, mesiac, rok] = termin.datum.split('.'); + const [hodina, minuty] = termin.cas.split(':'); + const dtstart = `${rok}${mesiac}${den}T${hodina}${minuty}00`; + + // as for there is no info about duration, we'll set it for 4 hours + let hodinaKoniec = (parseInt(hodina, 10) + 4).toString(); + // add leading zero + if (hodinaKoniec.length === 1) { + hodinaKoniec = '0' + hodinaKoniec; + } + const dtend = `${rok}${mesiac}${den}T${hodinaKoniec}${minuty}00`; + lines.push('DTSTART;TZID=Europe/Bratislava:' + dtstart); + lines.push('DTEND;TZID=Europe/Bratislava:' + dtend); + + // LOCATION + if (termin.miestnost) { + lines.push('LOCATION:' + termin.miestnost); + } + + // DESCRIPTION + //@TODO ake vsetky informacie chceme zobrazovat v popise eventu? (zatial su take, ako vo FAJR) + const desc = 'Prihlasovanie: ' + termin.prihlasovanie + '\n' + + 'Odhlasovanie: ' + termin.odhlasovanie + '\n' + + 'Poznámka: ' + termin.poznamka; + lines.push('DESCRIPTION:' + desc); + + lines.push('END:VEVENT'); + } + + // footer + lines.push('END:VCALENDAR'); + + return lines.map((l) => l.replace(/\n/g, '\\n')).join('\r\n'); +}; + +export class MojeSkuskyPageContent extends Component { + + renderContent = () => { + const cache = new CacheRequester(); + const { zapisnyListKey } = this.props.query; + + const vidim = cache.get('get_vidim_terminy_hodnotenia', zapisnyListKey); + + if (!cache.loadedAll) { + return ; + } + + if (!vidim) { + return

    Skúšky pre tento zápisný list už nie sú k dispozícii.

    ; + } + + const terminyPrihlasene = cache.get('get_prihlasene_terminy', zapisnyListKey); + const terminyVypisane = cache.get('get_vypisane_terminy', zapisnyListKey); + + if (!terminyPrihlasene || !terminyVypisane) { + return ; + } + + let terminy = {}; + terminyVypisane.forEach((termin) => {terminy[termin.termin_key] = termin;}); + terminyPrihlasene.forEach((termin) => {terminy[termin.termin_key] = termin;}); + terminy = Object.keys(terminy).map((key) => terminy[key]); + + let header; + [terminy, header] = sortTable( + terminy, MojeSkuskyColumns, this.props.query, 'skuskySort'); + + const message = terminy.length ? null : 'Zatiaľ nie sú vypísané žiadne termíny.'; + + const handleClickICal = () => { + const icalText = convertToICAL(terminyPrihlasene); + const blob = new Blob([icalText], { type: 'text/calendar;charset=utf-8' }); + FileSaver.saveAs(blob, 'MojeTerminy.ics', true); + }; + + return ( +
    + + {header} + + {terminy.map((termin) => ( + + {!termin.datum_prihlasenia || termin.datum_odhlasenia + ? + : + } + + + + + + + + + + + + ))} + + {message && } +
    {'\u2718'}{'\u2714'} + + {termin.nazov_predmetu} + + {termin.datum}{termin.cas}{termin.miestnost}{termin.hodnotiaci} + + {termin.pocet_prihlasenych + + (termin.maximalne_prihlasenych ? '/' + termin.maximalne_prihlasenych : '') + } + + {termin.poznamka}{termin.prihlasovanie}{termin.odhlasovanie} + {termin.hodnotenie_terminu + ? termin.hodnotenie_terminu + : ( + termin.hodnotenie_predmetu + ? termin.hodnotenie_predmetu + ' (nepriradená k termínu)' + : null + ) + } + +
    {message}
    + {terminy.length && } +
    + ); + } + + render() { + return ( +
    +
    + Moje skúšky +
    + {this.renderContent()} +
    + ); + } +} + +MojeSkuskyPageContent.propTypes = { + query: PropTypes.object.isRequired, +}; + +export class SkuskyRegisterButton extends Component { + + componentWillMount() { + this.setState({ pressed: false }); + } + + handleClick = () => { + const command = this.isSigninButton() ? 'prihlas_na_termin' : 'odhlas_z_terminu'; + const termin = this.props.termin; + + sendRpc(command, [termin.termin_key], (message) => { + if (message) { + this.setState({ pressed: false }); + alert(message); + } else { + RequestCache.invalidate('get_prihlasene_terminy'); + RequestCache.invalidate('get_vypisane_terminy'); + RequestCache.invalidate('get_prihlaseni_studenti'); + } + }); + + this.setState({ pressed: true }); + } + + isDisabled = () => { + const termin = this.props.termin; + return (this.isSigninButton() && termin.moznost_prihlasit !== 'A') || this.state.pressed; + } + + isSigninButton = () => { + const termin = this.props.termin; + return !termin.datum_prihlasenia || termin.datum_odhlasenia; + } + + render() { + const termin = this.props.termin; + + if (termin.hodnotenie_terminu) { + return null; + } + + const today = new Date() + .toJSON() + .replace(/-/g, '') + .substring(0, 8); + + if (today > sortAs.date(termin.datum)) { + return null; + } + + const buttonClass = 'btn btn-xs ' + + (this.isSigninButton() ? 'btn-success' : 'btn-danger') + + (this.isDisabled() ? ' appear-disabled' : ''); + const buttonText = this.state.pressed + ? + : ( + this.isSigninButton() + ? 'Prihlásiť' + : 'Odhlásiť' + ); + + return ( + + ); + } +} + +SkuskyRegisterButton.propTypes = { + termin: PropTypes.object.isRequired, +}; + +export class MojeSkuskyPage extends Component { + + render() { + return ( + + + + ); + } +} + +MojeSkuskyPage.propTypes = { + query: PropTypes.object.isRequired, +}; diff --git a/votrfront/js/src/PrehladStudiaPage.js b/votrfront/js/src/PrehladStudiaPage.js new file mode 100644 index 0000000..c317f67 --- /dev/null +++ b/votrfront/js/src/PrehladStudiaPage.js @@ -0,0 +1,173 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +import { CacheRequester, Loading } from './ajax'; +import { PageLayout, PageTitle } from './layout'; +import { sortAs, sortTable } from './sorting'; + +// TODO: Pridat kadejake sumarne informacie, aby to vyzeralo ako dashboard. +// TODO: Ked to raz bude rychle, pouzit to ako "home page" pri prazdnom action. +// TODO: Zvyraznit aktualne obdobia a pisat kolko casu zostava do dalsich. + +export const PrehladStudiumColumns = [ + ['Študijný program', 'sp_popis'], + ['Rok štúdia', 'rok_studia', sortAs.number], + ['Dĺžka v semestroch', 'sp_dlzka', sortAs.number], + ['Začiatok štúdia', 'zaciatok', sortAs.date], + ['Koniec štúdia', 'koniec', sortAs.date], + ['Doplňujúce údaje', 'sp_doplnujuce_udaje'], +]; +PrehladStudiumColumns.defaultOrder = 'd4'; + + +export const PrehladZapisnyListColumns = [ + ['Akademický rok', 'akademicky_rok'], + ['Študijný program', 'sp_popis'], + ['Ročník', 'rocnik', sortAs.number], + ['Dátum zápisu', 'datum_zapisu', sortAs.date], +]; +PrehladZapisnyListColumns.defaultOrder = 'd0d3'; + +export class PrehladStudiaPage extends Component { + + renderObdobie = (label, rpcName, arg) => { + const cache = new CacheRequester(); + const result = cache.get(rpcName, arg); + + return ( + + {label} + + {result + ? result.obdobie_od + ' \u2013 ' + result.obdobie_do + : + } + + + ); + } + + renderObdobia = () => { + // Obdobia predsalen neukazujeme, lebo AIS ma vacsinou zle informacie + // (skuskove je umelo predlzene kvoli moznosti zapisovat znamky, apod) a + // nechceme byt matuci. Zapnut sa daju tymto schovanym query flagom. + if (!this.props.query.reallyShowDates) { + return null; + } + + return ( + + + {this.renderObdobie('Zimný semester', 'get_semester_obdobie', 'Z')} + {this.renderObdobie('Zimné skúškové', 'get_skuskove_obdobie', 'Z')} + {this.renderObdobie('Letný semester', 'get_semester_obdobie', 'L')} + {this.renderObdobie('Letné skúškové', 'get_skuskove_obdobie', 'L')} + +
    + ); + } + + renderStudia() { + const cache = new CacheRequester(); + let studia = cache.get('get_studia'); + + if (!studia) { + return ; + } + + let header; + [studia, header] = sortTable( + studia, PrehladStudiumColumns, this.props.query, 'studiaSort'); + + const message = studia.length ? null : 'V AISe nemáte žiadne štúdiá.'; + + return ( + + {header} + + {studia.map((studium) => ( + + + + + + + + + ))} + + {message && } +
    {studium.sp_popis} ({studium.sp_skratka}){studium.rok_studia}{studium.sp_dlzka}{studium.zaciatok}{studium.koniec}{studium.sp_doplnujuce_udaje.replace(/^\((.*)\)$/, '$1')}
    {message}
    + ); + } + + renderZapisneListy() { + const cache = new CacheRequester(); + let studia = cache.get('get_studia'); + + if (!studia) { + return ; + } + + let zapisneListy = []; + + if (studia) { + studia.forEach((studium) => { + const mojeZapisneListy = cache.get('get_zapisne_listy', studium.studium_key); + if (mojeZapisneListy) { + mojeZapisneListy.forEach((zapisnyList) => { + zapisneListy.push(zapisnyList); + }); + } + }); + } + + let header; + [zapisneListy, header] = sortTable( + zapisneListy, PrehladZapisnyListColumns, this.props.query, 'zapisneListySort' + ); + + const showTable = zapisneListy.length || cache.loadedAll; + const message = zapisneListy.length ? null : 'V AISe nemáte žiadne zápisné listy.'; + + return ( + + {!cache.loadedAll && } + {showTable && + + {header} + + {zapisneListy.map((zapisnyList) => ( + + + + + + + ))} + + {message && } +
    {zapisnyList.akademicky_rok}{zapisnyList.sp_popis} ({zapisnyList.sp_skratka}){zapisnyList.rocnik}{zapisnyList.datum_zapisu}
    {message}
    } +
    + ); + } + + render() { + return ( + +
    + Prehľad štúdia +
    + {this.renderObdobia()} +

    Zoznam štúdií

    + {this.renderStudia()} +

    Zoznam zápisných listov

    + {this.renderZapisneListy()} +
    + ); + } +} + +PrehladStudiaPage.propTypes = { + query: PropTypes.object.isRequired, +}; diff --git a/votrfront/js/src/PriebezneHodnoteniaPage.js b/votrfront/js/src/PriebezneHodnoteniaPage.js new file mode 100644 index 0000000..a53164e --- /dev/null +++ b/votrfront/js/src/PriebezneHodnoteniaPage.js @@ -0,0 +1,99 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +import { ZapisnyListSelector } from './ZapisnyListSelector'; +import { CacheRequester, Loading } from './ajax'; +import { PageLayout, PageTitle } from './layout'; +import { Link } from './router'; +import { humanizeBoolean } from './humanizeAISData'; + +export class PriebezneHodnoteniaPageContent extends Component { + + renderContent = () => { + const cache = new CacheRequester(); + const { zapisnyListKey } = this.props.query; + let [priebezneHodnotenia, message] = cache.get('get_priebezne_hodnotenia', zapisnyListKey) || []; + + if (!priebezneHodnotenia) { + return ; + } + + if (!message && !priebezneHodnotenia.length) { + message = 'Tento zápisný list nemá žiadne priebežné hodnotenia.'; + } + + return ( +
    + {priebezneHodnotenia.map((priebHod, key) => ( +
    +

    + + {priebHod.nazov} + +

    + + + + + + + + + + + + {priebHod.zaznamy.map((zaznam, key) => ( + + + + + + + + ))} + +
    PopisBodyZaevidovalZapočítavaťMinimum
    {zaznam.dovod}{zaznam.poc_bodov} / {zaznam.maximum}{zaznam.zaevidoval}{humanizeBoolean(zaznam.zapocitavat)}{zaznam.minimum}
    +
    + ))} + {message && {message}} +
    + ); + } + + render() { + return ( +
    +
    + Priebežné hodnotenia +
    + {this.renderContent()} +
    + ); + } +} + +PriebezneHodnoteniaPageContent.propTypes = { + query: PropTypes.object.isRequired, +}; + +export class PriebezneHodnoteniaPage extends Component { + render() { + return ( + + + + ); + } +} + +PriebezneHodnoteniaPage.propTypes = { + query: PropTypes.object.isRequired, +}; diff --git a/votrfront/js/src/RegisterOsobPage.js b/votrfront/js/src/RegisterOsobPage.js new file mode 100644 index 0000000..2e07a6b --- /dev/null +++ b/votrfront/js/src/RegisterOsobPage.js @@ -0,0 +1,239 @@ +import React, { Component } from 'react'; +import { CacheRequester, Loading } from './ajax'; +import { currentAcademicYear } from './coursesStats'; +import { FormItem, PageLayout, PageTitle } from './layout'; +import { navigate } from './router'; +import { sortAs, sortTable } from './sorting'; + + +export const RegisterOsobColumns = [ + ['Plné meno', 'plne_meno', sortAs.personName], + ['E-mail', 'email'], +]; +RegisterOsobColumns.defaultOrder = 'a0'; + +export class RegisterOsobForm extends Component { + componentWillMount() { + const query = this.props.query; + + this.setState({ + meno: query.meno, + priezvisko: query.priezvisko, + absolventi: query.absolventi, + studenti: query.studenti, + zamestnanci: query.zamestnanci, + akademickyRok: query.akademickyRok || currentAcademicYear(), + fakulta: query.fakulta, + skratkaSp: query.skratkaSp, + uchadzaciRocnik: query.uchadzaciRocnik, + prvyRocnik: query.prvyRocnik, + druhyRocnik: query.druhyRocnik, + tretiRocnik: query.tretiRocnik, + stvrtyRocnik: query.stvrtyRocnik, + piatyRocnik: query.piatyRocnik, + siestyRocnik: query.siestyRocnik, + siedmyRocnik: query.siedmyRocnik, + osmyRocnik: query.osmyRocnik, + absolventiRocnik: query.absolventiRocnik, + }); + } + + handleFieldChange = (event) => { + this.setState({ [event.target.name]: event.target.value }); + } + + handleCheckBoxChange = (event) => { + this.setState({ [event.target.name]: String(event.target.checked) }); + } + + handleSubmit = (event) => { + event.preventDefault(); + navigate({ action: 'registerOsob', ...this.state }); + } + + renderTextInput = (label, name, focus) => { + return ( + + + + ); + } + + renderSelect = (label, name, items, cache) => { + return ( + + {items ? + : } + + ); + } + + renderCheckbox = (label, name) => { + return ( + + ); + } + + render() { + const cache = new CacheRequester(); + const akademickeRoky = cache.get('get_register_osob_akademicky_rok_options'); + const fakulty = cache.get('get_register_osob_fakulty'); + + return ( +
    + {this.renderTextInput('Priezvisko: ', 'priezvisko', true)} + {this.renderTextInput('Meno: ', 'meno', false)} + {this.renderSelect('Fakulta: ', 'fakulta', fakulty, cache)} + {this.renderTextInput('Študijný program (skratka): ', 'skratkaSp', false)} + {this.renderSelect('Akademický rok: ', 'akademickyRok', akademickeRoky, cache)} +
    +
    Typ osoby:
    +
    + {this.renderCheckbox(' Absolventi ', 'absolventi')} + {this.renderCheckbox(' Študenti ', 'studenti')} + {this.renderCheckbox(' Zamestnanci ', 'zamestnanci')} +
    +
    +
    +
    Rok štúdia:
    +
    + {this.renderCheckbox(' 1. ', 'prvyRocnik')} + {this.renderCheckbox(' 2. ', 'druhyRocnik')} + {this.renderCheckbox(' 3. ', 'tretiRocnik')} + {this.renderCheckbox(' 4. ', 'stvrtyRocnik')} + {this.renderCheckbox(' 5. ', 'piatyRocnik')} + {this.renderCheckbox(' 6. ', 'siestyRocnik')} + {this.renderCheckbox(' 7. ', 'siedmyRocnik')} + {this.renderCheckbox(' 8. ', 'osmyRocnik')} +
    + {this.renderCheckbox(' Uchádzači ', 'uchadzaciRocnik')} + {this.renderCheckbox(' Absolventi ', 'absolventiRocnik')} +
    +
    + + + +
    + ); + } +} + +export class RegisterOsobResultTable extends Component { + render() { + const cache = new CacheRequester(); + const query = this.props.query; + + if (!query.akademickyRok || + !(query.meno || + query.priezvisko || + query.absolventi === 'true' || + query.studenti === 'true' || + query.zamestnanci === 'true' || + query.fakulta || + query.skratkaSp || + query.uchadzaciRocnik === 'true' || + query.prvyRocnik === 'true' || + query.druhyRocnik === 'true' || + query.tretiRocnik === 'true' || + query.stvrtyRocnik === 'true' || + query.piatyRocnik === 'true' || + query.siestyRocnik === 'true' || + query.siedmyRocnik === 'true' || + query.osmyRocnik === 'true' || + query.absolventiRocnik === 'true')) { + return null; + } + + const response = cache.get('vyhladaj_osobu', + query.meno, + query.priezvisko, + query.absolventi === 'true', + query.studenti === 'true', + query.zamestnanci === 'true', + query.akademickyRok, + query.fakulta, + query.skratkaSp, + query.uchadzaciRocnik === 'true', + query.prvyRocnik === 'true', + query.druhyRocnik === 'true', + query.tretiRocnik === 'true', + query.stvrtyRocnik === 'true', + query.piatyRocnik === 'true', + query.siestyRocnik === 'true', + query.siedmyRocnik === 'true', + query.osmyRocnik === 'true', + query.absolventiRocnik === 'true' + ); + + if (!response) { + return ; + } + + let [osoby, message] = response; + let header; + [osoby, header] = sortTable( + osoby, RegisterOsobColumns, this.props.query, 'osobySort'); + + if (!message && !osoby.length) { + message = 'Podmienkam nevyhovuje žiadny záznam.'; + } + + return ( +
    +

    Výsledky

    + + {header} + + {osoby.map((osoba, index) => ( + + + + + ))} + + {message && } +
    {osoba.plne_meno}{osoba.email && + {osoba.email}} +
    {message}
    +
    + ); + } +} + +export class RegisterOsobPage extends Component { + render() { + return ( + +
    + Register osôb +
    + + +
    + ); + } +} diff --git a/votrfront/js/src/RegisterPredmetovPage.js b/votrfront/js/src/RegisterPredmetovPage.js new file mode 100644 index 0000000..4885720 --- /dev/null +++ b/votrfront/js/src/RegisterPredmetovPage.js @@ -0,0 +1,194 @@ +import React, { Component } from 'react'; + +import { CacheRequester, Loading } from './ajax'; +import { currentAcademicYear } from './coursesStats'; +import { classForSemester, humanizeBoolean } from './humanizeAISData'; +import { FormItem, PageLayout, PageTitle } from './layout'; +import { Link, navigate } from './router'; +import { sortAs, sortTable } from './sorting'; + + +export const RegisterPredmetovColumns = [ + ['Názov predmetu', 'nazov'], + ['Skratka predmetu', 'skratka'], + ['Fakulta', 'fakulta'], + [Sem., 'semester'], + ['Rozsah výučby', 'rozsah_vyucby'], + ['Počet kreditov', 'kredit', sortAs.number], + ['Konanie', 'konanie'], +]; +RegisterPredmetovColumns.defaultOrder = 'a0'; + +export class RegisterPredmetovForm extends Component { + componentWillMount() { + const query = this.props.query; + + this.setState({ + fakulta: query.fakulta, + stredisko: query.stredisko, + semester: query.semester, + stupen: query.stupen, + studijnyProgramSkratka: query.studijnyProgramSkratka, + skratkaPredmetu: query.skratkaPredmetu, + nazovPredmetu: query.nazovPredmetu, + akademickyRok: query.akademickyRok || currentAcademicYear(), + }); + } + + handleFieldChange = (event) => { + this.setState({ [event.target.name]: event.target.value }); + } + + handleSubmit = (event) => { + event.preventDefault(); + navigate({ action: 'registerPredmetov', ...this.state }); + } + + renderTextInput = (label, name, focus) => { + return ( + + + + ); + } + + renderSelect(label, name, items, cache) { + return ( + + {items ? + : } + + ); + } + + render() { + const cache = new CacheRequester(); + const fakulty = cache.get('get_register_predmetov_fakulta_options'); + const rocniky = cache.get('get_register_predmetov_akademicky_rok_options'); + const stupne = cache.get('get_register_predmetov_stupen_options'); + const semestre = cache.get('get_register_predmetov_semester_options'); + + return ( +
    + {this.renderTextInput('Názov predmetu: ', 'nazovPredmetu', true)} + {this.renderTextInput('Skratka predmetu: ', 'skratkaPredmetu', false)} + {this.renderTextInput('Študijný program (skratka): ', 'studijnyProgramSkratka', false)} + {this.renderSelect('Fakulta: ', 'fakulta', fakulty, cache)} + {this.renderTextInput('Stredisko: ', 'stredisko', false)} + {this.renderSelect('Stupeň: ', 'stupen', stupne, cache)} + {this.renderSelect('Akademický rok: ', 'akademickyRok', rocniky, cache)} + {this.renderSelect('Semester: ', 'semester', semestre, cache)} + + + +
    + ); + } +} + +export class RegisterPredmetovResultTable extends Component { + render() { + const cache = new CacheRequester(); + const query = this.props.query; + if (!query.fakulta && + !query.stredisko && + !query.studijnyProgramSkratka && + !query.skratkaPredmetu && + !query.nazovPredmetu && + !query.semester && + !query.stupen) { + return null; + } + + if (!query.akademickyRok) { + return null; + } + + const response = cache.get('vyhladaj_predmety', + query.akademickyRok, + query.fakulta || null, + query.stredisko || null, + query.studijnyProgramSkratka || null, + query.skratkaPredmetu || null, + query.nazovPredmetu || null, + query.semester || null, + query.stupen || null); + + if (!response) { + return ; + } + + let [rows, message] = response; + let header; + [rows, header] = sortTable( + rows, RegisterPredmetovColumns, this.props.query, 'predmetSort'); + + if (!message && !rows.length) { + message = 'Podmienkam nevyhovuje žiadny záznam.'; + } + + return ( +
    +

    Výsledky

    + + {header} + + {rows.map((predmet) => ( + + + + + + + + + + ))} + + {message && } +
    + + {predmet.nazov} + + {predmet.skratka}{predmet.fakulta}{predmet.semester}{predmet.rozsah_vyucby}{predmet.kredit}{humanizeBoolean(predmet.konanie)}
    {message}
    +
    + ); + } +} + +export class RegisterPredmetovPage extends Component { + render() { + return ( + +
    + Register predmetov +
    + + +
    + ); + } +} diff --git a/votrfront/js/src/StudiumSelector.js b/votrfront/js/src/StudiumSelector.js new file mode 100644 index 0000000..f5ac71d --- /dev/null +++ b/votrfront/js/src/StudiumSelector.js @@ -0,0 +1,91 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +import { CacheRequester, Loading } from './ajax'; +import { Link } from './router'; +import { sortAs } from './sorting'; + + +// TODO: Reduce code duplication with ZapisnyListSelector. + +export class StudiumSelector extends Component { + + getItems = (cache) => { + const studia = cache.get('get_studia'); + const items = studia ? [...studia] : []; + + return items.sort((a, b) => { + const d1 = sortAs.date(a.zaciatok); + const d2 = sortAs.date(b.zaciatok); + + if (d1 < d2) { + return -1; + } else if (d1 > d2) { + return 1; + } + return 0; + }).reverse(); + } + + renderSelector = (cache, items, query) => { + return ( +
      +
    • Štúdium:
    • + {items.map((studium) => { + const key = studium.studium_key; + const active = key === query.studiumKey; + return ( +
    • + + {studium.sp_skratka} + +
    • + ); + })} + {cache.loadedAll + ? null + : ( +
    • + + + +
    • + ) + } +
    + ); + } + + renderPage = (cache, items, query) => { + if (query.studiumKey) { + return ; + } + if (cache.loadedAll && items.length === 0) { + return

    Žiadne štúdiá.

    ; + } + return null; + } + + render() { + const cache = new CacheRequester(); + const items = this.getItems(cache); + let query = this.props.query; + + if (!query.studiumKey && cache.loadedAll && items.length) { + const mostRecentItem = items[0]; + query = { ...query, studiumKey: mostRecentItem.studium_key }; + } + + return ( +
    + {this.renderSelector(cache, items, query)} + {this.renderPage(cache, items, query)} +
    + ); + } +} + +StudiumSelector.propTypes = { + query: PropTypes.object.isRequired, + component: PropTypes.func.isRequired, +}; diff --git a/votrfront/js/src/ZapisPage.js b/votrfront/js/src/ZapisPage.js new file mode 100644 index 0000000..e3a107a --- /dev/null +++ b/votrfront/js/src/ZapisPage.js @@ -0,0 +1,742 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +import { ZapisnyListSelector } from './ZapisnyListSelector'; +import { CacheRequester, Loading, RequestCache, sendRpc } from './ajax'; +import { coursesStats } from './coursesStats'; +import { humanizeTypVyucby, plural } from './humanizeAISData'; +import { FormItem, PageLayout, PageTitle } from './layout'; +import { Link, navigate } from './router'; +import { sortAs, sortTable } from './sorting'; + + +export const ZapisZPlanuColumns = [ + ['Moje?', 'moje', null, true], + [Typ, 'typ_vyucby'], + [ + 'Blok', + null, + (predmet) => ( + parseInt(predmet.blok_index || 0, 10) * 1000 + + parseInt(predmet.v_bloku_index || 0, 10) + ), + ], + ['Názov predmetu', 'nazov'], + ['Skratka predmetu', 'skratka'], + [Sem., 'semester', null, true], + ['Rozsah výučby', 'rozsah_vyucby'], + ['Kredit', 'kredit', sortAs.number], + ['Prihlásení', 'pocet_prihlasenych', sortAs.number], + [Odp. ročník, 'odporucany_rocnik'], + ['Jazyk', 'jazyk'], +]; +ZapisZPlanuColumns.defaultOrder = 'a1a2a9a3'; + + +export const ZapisZPonukyColumns = [ + ['Moje?', 'moje', null, true], + [Typ, 'typ_vyucby'], + ['Blok', 'blok_skratka'], + ['Názov predmetu', 'nazov'], + ['Skratka predmetu', 'skratka'], + [Sem., 'semester', null, true], + ['Rozsah výučby', 'rozsah_vyucby'], + ['Kredit', 'kredit', sortAs.number], + ['Prihlásení', 'pocet_prihlasenych', sortAs.number], + ['Jazyk', 'jazyk'], +]; +ZapisZPonukyColumns.defaultOrder = 'a3'; + +export const ZapisVlastnostiColumns = [ + ['Skratka', 'skratka'], + ['Názov', 'nazov'], + ['Minimálny kredit', 'minimalny_kredit'], + ['Poznámka', 'poznamka'], +]; + +export class ZapisMenu extends Component { + + renderLink = (content, href, active) => { + return ( + + {content} + + ); + } + + render() { + const { action, cast, zapisnyListKey } = this.props.query; + return ( +
    +
    + Zápis predmetov +
    +
    + {this.renderLink('Môj študijný plán', + { action: 'zapisZPlanu', cast: 'SC', zapisnyListKey }, + action === 'zapisZPlanu' && cast !== 'SS')} + {this.renderLink('Predmety štátnej skúšky', + { action: 'zapisZPlanu', cast: 'SS', zapisnyListKey }, + action === 'zapisZPlanu' && cast === 'SS')} + {this.renderLink('Hľadať ďalšie predmety', + { action: 'zapisZPonuky', zapisnyListKey }, + action === 'zapisZPonuky')} +
    +
    +
    +
    {this.props.children}
    +
    + ); + } +} + +ZapisMenu.propTypes = { + query: PropTypes.object.isRequired, +}; + +export class ZapisTableFooter extends Component { + + constructor(props) { + super(props); + this.state = this.parseBloky(props); + } + + parseBloky = (props) => { + const bloky = {}, nazvy = {}, semestre = {}; + bloky[''] = []; + + Object + .keys(props.predmety) + .forEach((predmetKey) => { + const predmet = props.predmety[predmetKey]; + semestre[predmet.semestre] = true; + nazvy[predmet.blok_skratka] = predmet.blok_nazov; + }); + + Object + .keys(nazvy) + .sort() + .forEach((skratka) => {bloky[skratka] = [];}); + + Object + .keys(props.predmety) + .forEach((predmetKey) => { + const predmet = props.predmety[predmetKey]; + if (!props.moje[predmet.predmet_key]) { + return; + } + if (predmet.blok_skratka) { + bloky[predmet.blok_skratka].push(predmet); + }; + bloky[''].push(predmet); + }); + + const jedinySemester = Object.keys(semestre).length <= 1; + + return { bloky, nazvy, semestre, jedinySemester }; + } + + componentWillReceiveProps(nextProps) { + this.setState(this.parseBloky(nextProps)); + } + + renderBlok = ({ blok, skratka }) => { + const stats = coursesStats(blok); + const { nazvy, jedinySemester } = this.state; + + return ( + + {skratka ? 'Súčet bloku' : 'Dokopy'} + + {nazvy[skratka] + ? {skratka} + : skratka + } + + + {stats.spolu.count} {plural(stats.spolu.count, 'predmet', 'predmety', 'predmetov')} + {!jedinySemester && ` (${stats.zima.count} v zime, ${stats.leto.count}) v lete)`} + + + {stats.spolu.creditsCount} + {!jedinySemester && ` (${stats.zima.creditsCount}+${stats.leto.creditsCount})`} + + + + ); + } + + render() { + return ( + + {Object + .keys(this.state.bloky) + .map((skratka) => ({ skratka, blok: this.state.bloky[skratka] })) + .map(this.renderBlok) + } + + ); + } +} + +ZapisTableFooter.propTypes = { + predmety: PropTypes.object.isRequired, + moje: PropTypes.object.isRequired, +}; + +export class ZapisTable extends Component { + + componentWillMount() { + this.setState({ + odoberanePredmety: {}, + pridavanePredmety: {}, + }); + } + + handleChange = (event) => { + const predmetKey = event.target.name; + const predmet = this.props.predmety[predmetKey]; + + delete this.state.odoberanePredmety[predmetKey]; + delete this.state.pridavanePredmety[predmetKey]; + if (predmet.moje && !event.target.checked) { + this.state.odoberanePredmety[predmetKey] = true; + } + if (!predmet.moje && event.target.checked) { + this.state.pridavanePredmety[predmetKey] = true; + } + + this.forceUpdate(); + } + + handleSave = (event) => { + event.preventDefault(); + + if (this.state.saving) { + return; + } + + const predmety = this.props.predmety; + + const odoberanePredmety = [], pridavanePredmety = []; + + Object.keys(predmety).forEach((predmetKey) => { + if (this.state.odoberanePredmety[predmetKey] && predmety[predmetKey].moje) { + odoberanePredmety.push(predmety[predmetKey]); + } + if (this.state.pridavanePredmety[predmetKey] && !predmety[predmetKey].moje) { + pridavanePredmety.push(predmety[predmetKey]); + } + }); + + this.setState({ saving: true }); + + const koniec = (odobral, pridal) => { + if (odobral) { + odoberanePredmety.forEach((predmet) => { + RequestCache['pocet_prihlasenych_je_stary' + predmet.predmet_key] = true; + }); + this.setState({ odoberanePredmety: {} }); + } + + if (pridal) { + pridavanePredmety.forEach((predmet) => { + RequestCache['pocet_prihlasenych_je_stary' + predmet.predmet_key] = true; + }); + this.setState({ pridavanePredmety: {} }); + } + + // Aj ked skoncime neuspechom, je mozne, ze niektore predmety sa zapisali. + RequestCache.invalidate('get_hodnotenia'); + RequestCache.invalidate('get_predmety'); + RequestCache.invalidate('get_prehlad_kreditov'); + RequestCache.invalidate('get_studenti_zapisani_na_predmet'); + RequestCache.invalidate('zapis_get_zapisane_predmety'); + }; + + this.props.odoberPredmety(odoberanePredmety, (message) => { + if (message) { + this.setState({ saving: false }); + alert(message); + koniec(false, false); + } else { + this.props.pridajPredmety(pridavanePredmety, (message) => { + this.setState({ saving: false }); + if (message) { + alert(message); + koniec(true, false); + } else { + koniec(true, true); + } + }); + } + }); + } + + render() { + // Chceme, aby sa pre ZapisTable zachoval this.state aj vtedy, ked tabulku + // nevidno, lebo sme prave zapisali predmety a obnovujeme zoznam predmetov. + // Takze komponent ZapisTable sa bude renderovat vzdy, aby nikdy nezanikol + // a neprisiel o state. Niekedy proste nedostane this.props.predmety. + if (!this.props.predmety || !this.props.akademickyRok) { + return ; + } + + const { columns, query, message } = this.props; + let { predmety } = this.props; + + const classes = {}, checked = {}; + + Object.keys(predmety).forEach((predmetKey) => { + checked[predmetKey] = predmety[predmetKey].moje; + if (this.state.odoberanePredmety[predmetKey] && predmety[predmetKey].moje) { + classes[predmetKey] = 'danger'; + checked[predmetKey] = false; + } + if (this.state.pridavanePredmety[predmetKey] && !predmety[predmetKey].moje) { + classes[predmetKey] = 'success'; + checked[predmetKey] = true; + } + }); + + const saveButton = ( +
    + +
    + ); + + let header; + [predmety, header] = sortTable( + Object.keys(predmety).map((key) => predmety[key]), + columns, + query, + 'predmetySort' + ); + + return ( +
    + {saveButton} + + {header} + + {predmety.map((predmet) => { + const predmetKey = predmet.predmet_key; + const href = { + ...this.props.query, + modal: 'detailPredmetu', + modalPredmetKey: predmet.predmet_key, + modalAkademickyRok: this.props.akademickyRok, + }; + let nazov = {predmet.nazov}; + if (predmet.moje) { + nazov = {nazov}; + } + if (predmet.aktualnost) { + nazov = {nazov} (nekoná sa); + } + let blok = predmet.blok_skratka; + if (predmet.blok_nazov) { + blok = {blok}; + } + + return ( + + + + + + + + + + + {columns === ZapisZPlanuColumns && } + + + ); + })} + + {this.props.showFooter && } + {message && } +
    + + + + {predmet.typ_vyucby} + + {blok}{nazov}{predmet.skratka}{predmet.semester}{predmet.rozsah_vyucby}{predmet.kredit} + {RequestCache['pocet_prihlasenych_je_stary' + predmetKey] + ? ({predmet.pocet_prihlasenych}) + : predmet.pocet_prihlasenych + } + {predmet.maximalne_prihlasenych && '/' + predmet.maximalne_prihlasenych} + {predmet.odporucany_rocnik}{predmet.jazyk.replace(/ ,/g, ', ')}
    {message}
    + {saveButton} +
    + ); + } +} + +ZapisTable.propTypes = { + query: PropTypes.object.isRequired, + predmety: PropTypes.object, + akademickyRok: PropTypes.string, + message: PropTypes.node, + columns: PropTypes.array.isRequired, + showFooter: PropTypes.bool, + odoberPredmety: PropTypes.func.isRequired, + pridajPredmety: PropTypes.func.isRequired, +}; + +export class ZapisVlastnostiTable extends Component { + + render() { + const cache = new CacheRequester(); + const { zapisnyListKey } = this.props.query; + + let [vlastnosti, message] = cache.get('zapis_get_vlastnosti_programu', zapisnyListKey) || []; + + if (!vlastnosti) { + return ; + } + + if (!message && !vlastnosti.length) { + message = 'Študijný plán nemá žiadne poznámky.'; + } + + let header; + [vlastnosti, header] = sortTable( + vlastnosti, ZapisVlastnostiColumns, this.props.query, 'vlastnostiSort'); + + return ( + + {header} + + {vlastnosti.map((vlastnost, index) => ( + + + + + + + ))} + + {message && } +
    {vlastnost.skratka}{vlastnost.nazov}{vlastnost.minimalny_kredit}{vlastnost.poznamka}
    {message}
    + ); + } +} + +ZapisVlastnostiTable.propTypes = { + query: PropTypes.object.isRequired, +}; + +export class ZapisZPlanuPageContent extends Component { + getQuery = () => { + let { zapisnyListKey, cast } = this.props.query; + cast = (cast === 'SS' ? 'SS' : 'SC'); + return { zapisnyListKey, cast }; + } + + render() { + const cache = new CacheRequester(); + const { zapisnyListKey, cast } = this.getQuery(); + + const [zapisanePredmety, zapisaneMessage] = cache.get( + 'zapis_get_zapisane_predmety', zapisnyListKey, cast + ) || []; + const [ponukanePredmety, ponukaneMessage] = cache.get( + 'zapis_plan_vyhladaj', zapisnyListKey, cast + ) || []; + const akademickyRok = cache.get('zapisny_list_key_to_akademicky_rok', zapisnyListKey); + + let outerMessage, tableMessage, predmety = {}; + + if (zapisaneMessage || ponukaneMessage) { + outerMessage =

    {zapisaneMessage || ponukaneMessage}

    ; + } else if (!cache.loadedAll) { + outerMessage = ; + } else { + let vidnoZimne = false; + + ponukanePredmety.forEach((predmet) => { + predmety[predmet.predmet_key] = { moje: false, ...predmet }; + if (predmet.semester === 'Z') { + vidnoZimne = true; + } + }); + zapisanePredmety.forEach((predmet) => { + const predmetKey = predmet.predmet_key; + if (!predmety[predmetKey]) { + if (predmet.semester === 'Z' && !vidnoZimne) { + return; + } + predmety[predmetKey] = { moje: true, ...predmet }; + } else { + for (let property in predmet) { + if (predmet[property] !== null && predmet[property] !== undefined) { + predmety[predmetKey][property] = predmet[property]; + } + } + predmety[predmetKey].moje = true; + } + }); + + if (Object.keys(predmety).length === 0) { + tableMessage = 'Zoznam ponúkaných predmetov je prázdny.'; + } + } + + return ( + + {outerMessage} + +

    Poznámky k študijnému plánu

    + +
    + ); + } + + pridajPredmety = (predmety, callback) => { + if (!predmety.length) { + return callback(null); + } + + const { zapisnyListKey, cast } = this.getQuery(); + const dvojice = predmety.map((predmet) => [predmet.typ_vyucby, predmet.skratka]); + sendRpc('zapis_plan_pridaj_predmety', [zapisnyListKey, cast, dvojice], callback); + } + + odoberPredmety = (predmety, callback) => { + if (!predmety.length) { + return callback(null); + } + + const { zapisnyListKey, cast } = this.getQuery(); + const kluce = predmety.map((predmet) => predmet.predmet_key); + sendRpc('zapis_odstran_predmety', [zapisnyListKey, cast, kluce], callback); + } +} + +export class ZapisZPlanuPage extends Component { + + render() { + return ( + + + + ); + } +} + +ZapisZPlanuPage.propTypes = { + query: PropTypes.object.isRequired, +}; + +export class ZapisZPonukyForm extends Component { + componentWillMount() { + const query = this.props.query; + + this.setState({ + fakulta: query.fakulta, + stredisko: query.stredisko, + skratkaPredmetu: query.skratkaPredmetu, + nazovPredmetu: query.nazovPredmetu, + }); + } + + handleFieldChange = (event) => { + this.setState({ [event.target.name]: event.target.value }); + } + + handleSubmit = (event) => { + event.preventDefault(); + const { zapisnyListKey } = this.props.query; + navigate({ action: 'zapisZPonuky', zapisnyListKey, ...this.state }); + } + + renderTextInput = (label, name, focus) => { + return ( + + + + ); + } + + renderSelect = (label, name, items, cache) => { + return ( + + {items ? + : } + + ); + } + + render() { + const cache = new CacheRequester(); + const [fakulty, message] = cache.get('zapis_ponuka_options', this.props.query.zapisnyListKey) || []; + + if (!fakulty) { + return ; + } + + if (message) { + return

    {message}

    ; + } + + return ( +
    + {this.renderTextInput('Názov predmetu: ', 'nazovPredmetu', true)} + {this.renderTextInput('Skratka predmetu: ', 'skratkaPredmetu', false)} + {this.renderSelect('Fakulta: ', 'fakulta', fakulty, cache)} + {this.renderTextInput('Stredisko: ', 'stredisko', false)} + + + +
    + ); + } +} + +export class ZapisZPonukyPageContent extends Component { + + render() { + const cache = new CacheRequester(); + const query = this.props.query; + + let outerMessage, tableMessage, predmety, akademickyRok; + + if (query.fakulta || + query.stredisko || + query.skratkaPredmetu || + query.nazovPredmetu) { + const [zapisanePredmety, zapisaneMessage] = cache.get( + 'zapis_get_zapisane_predmety', query.zapisnyListKey, 'SC' + ) || []; + const [ponukanePredmety, ponukaneMessage] = cache.get('zapis_ponuka_vyhladaj', query.zapisnyListKey, + query.fakulta || null, + query.stredisko || null, + query.skratkaPredmetu || null, + query.nazovPredmetu || null) || []; + akademickyRok = cache.get('zapisny_list_key_to_akademicky_rok', query.zapisnyListKey); + + if (zapisaneMessage) { + outerMessage =

    {zapisaneMessage}

    ; + } else if (!cache.loadedAll) { + outerMessage = ; + } else { + predmety = {}; + ponukanePredmety.forEach((predmet) => { + predmety[predmet.predmet_key] = { moje: false, ...predmet }; + }); + zapisanePredmety.forEach((predmet) => { + if (predmety[predmet.predmet_key]) { + predmety[predmet.predmet_key].moje = true; + } + }); + + tableMessage = ponukaneMessage; + if (Object.keys(predmety) === 0 && !tableMessage) { + tableMessage = 'Podmienkam nevyhovuje žiadny záznam.'; + } + } + } + + return ( + + + {outerMessage} + {predmety &&

    Výsledky

    } + +
    + ); + } + + pridajPredmety = (predmety, callback) => { + if (!predmety.length) { + return callback(null); + } + + const query = this.props.query; + const skratky = predmety.map((predmet) => predmet.skratka); + sendRpc('zapis_ponuka_pridaj_predmety', [query.zapisnyListKey, + query.fakulta || null, + query.stredisko || null, + query.skratkaPredmetu || null, + query.nazovPredmetu || null, + skratky], callback); + } + + odoberPredmety(predmety, callback) { + if (!predmety.length) { + return callback(null); + } + + const query = this.props.query; + const kluce = predmety.map((predmet) => predmet.predmet_key); + sendRpc('zapis_odstran_predmety', [query.zapisnyListKey, 'SC', kluce], callback); + } +} + +export class ZapisZPonukyPage extends Component { + + render() { + return ( + + + + ); + } +} + +ZapisZPonukyPage.propTypes = { + query: PropTypes.object.isRequired, +}; diff --git a/votrfront/js/src/ZapisnyListSelector.js b/votrfront/js/src/ZapisnyListSelector.js new file mode 100644 index 0000000..75cd3bb --- /dev/null +++ b/votrfront/js/src/ZapisnyListSelector.js @@ -0,0 +1,95 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +import { CacheRequester, Loading } from './ajax'; +import { Link } from './router'; +import { sortAs } from './sorting'; + +export class ZapisnyListSelector extends Component { + getItems = (cache) => { + const studia = cache.get('get_studia'); + const items = []; + + if (studia) { + studia.forEach((studium) => { + const zapisneListy = cache.get('get_zapisne_listy', studium.studium_key); + if (zapisneListy) { + items.push(...zapisneListy); + } + }); + } + + return items.sort((a, b) => { + const d1 = sortAs.date(a.datum_zapisu); + const d2 = sortAs.date(b.datum_zapisu); + + if (d1 < d2) { + return -1; + } else if (d1 > d2) { + return 1; + } + return 0; + }).reverse(); + } + + renderSelector = (cache, items, query) => { + return ( +
      +
    • + + Zápisný list: + +
    • + {items.map((zapisnyList) => { + const key = zapisnyList.zapisny_list_key; + const active = key === query.zapisnyListKey; + return ( +
    • + + {zapisnyList.akademicky_rok} {zapisnyList.sp_skratka} + +
    • + ); + })} + {cache.loadedAll ? null : ( +
    • + +
    • + )} +
    + ); + } + + renderPage = (cache, items, query) => { + if (query.zapisnyListKey) { + return ; + } + if (cache.loadedAll && items.length === 0) { + return

    Žiadne zápisné listy.

    ; + } + return null; + } + + render() { + const cache = new CacheRequester(); + const items = this.getItems(cache); + let query = this.props.query; + + if (!query.zapisnyListKey && cache.loadedAll && items.length) { + const mostRecentItem = items[0]; + query = { ...query, zapisnyListKey: mostRecentItem.zapisny_list_key }; + } + + return ( +
    + {this.renderSelector(cache, items, query)} + {this.renderPage(cache, items, query)} +
    + ); + } +} + +ZapisnyListSelector.propTypes = { + query: PropTypes.object.isRequired, + component: PropTypes.func.isRequired, +}; diff --git a/votrfront/js/src/ZoznamPrihlasenychNaTermin.js b/votrfront/js/src/ZoznamPrihlasenychNaTermin.js new file mode 100644 index 0000000..3c0c177 --- /dev/null +++ b/votrfront/js/src/ZoznamPrihlasenychNaTermin.js @@ -0,0 +1,70 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +import { CacheRequester, Loading } from './ajax'; +import { Modal } from './layout'; +import { sortAs, sortTable } from './sorting'; + +export const ZoznamPrihlasenychNaTerminColumns = [ + ['Meno', 'plne_meno', sortAs.personName], + ['Študijný program', 'sp_skratka'], + ['Ročník', 'rocnik', sortAs.number], + ['E-mail', 'email'], + ['Dátum prihlásenia', 'datum_prihlasenia', sortAs.date], +]; + +export class ZoznamPrihlasenychNaTerminModal extends Component { + + renderContent = () => { + const cache = new CacheRequester(); + const { modalTerminKey } = this.props.query; + + if (!modalTerminKey) { + return null; + } + let studenti = cache.get('get_prihlaseni_studenti', modalTerminKey); + + if (!studenti) { + return ; + } + + let header; + [studenti, header] = sortTable( + studenti, ZoznamPrihlasenychNaTerminColumns, + this.props.query, 'modalStudentiSort'); + + const message = studenti.length ? null : 'Na termín nie sú prihlásení žiadni študenti.'; + + return ( + + {header} + + {studenti.map((student, index) => ( + + + + + + + + ))} + + {message && } +
    {student.plne_meno}{student.sp_skratka}{student.rocnik}{student.email && + {student.email}} + {student.datum_prihlasenia}
    {message}
    + ); + } + + render() { + return ( + + {this.renderContent()} + + ); + } +} + +ZoznamPrihlasenychNaTerminModal.propTypes = { + query: PropTypes.object.isRequired, +}; diff --git a/votrfront/js/src/actions.js b/votrfront/js/src/actions.js new file mode 100644 index 0000000..012a7a2 --- /dev/null +++ b/votrfront/js/src/actions.js @@ -0,0 +1,94 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +import { AboutModal, IndexPage } from './About'; +import { DetailPredmetuModal } from './DetailPredmetu'; +import { ErrorModal } from './ErrorPage'; +import { LogViewer } from './LogViewer'; +import { MojeHodnoteniaPage } from './MojeHodnoteniaPage'; +import { PriebezneHodnoteniaPage } from './PriebezneHodnoteniaPage'; +import { MojePredmetyPage } from './MojePredmetyPage'; +import { MojeSkuskyPage } from './MojeSkuskyPage'; +import { PrehladStudiaPage } from './PrehladStudiaPage'; +import { RegisterOsobPage } from './RegisterOsobPage'; +import { RegisterPredmetovPage } from './RegisterPredmetovPage'; +import { ZapisZPlanuPage, ZapisZPonukyPage } from './ZapisPage'; +import { ZoznamPrihlasenychNaTerminModal } from './ZoznamPrihlasenychNaTermin'; +import { ModalBase, PageLayout } from './layout'; +import { navigate } from './router'; +import { AnketaPopup } from './AnketaPopup'; + +export class NotFoundPage extends Component { + render() { + return ( + +

    Action not found!

    +
    + ); + } +} + +export const actions = { + index: IndexPage, + priebezneHodnotenia: PriebezneHodnoteniaPage, + mojeHodnotenia: MojeHodnoteniaPage, + mojePredmety: MojePredmetyPage, + mojeSkusky: MojeSkuskyPage, + prehladStudia: PrehladStudiaPage, + registerOsob: RegisterOsobPage, + registerPredmetov: RegisterPredmetovPage, + zapisZPlanu: ZapisZPlanuPage, + zapisZPonuky: ZapisZPonukyPage, +}; + +export const modalActions = { + about: AboutModal, + detailPredmetu: DetailPredmetuModal, + zoznamPrihlasenychNaTermin: ZoznamPrihlasenychNaTerminModal, +}; + +export class App extends Component { + + handleModalClose = () => { + if (Votr.ajaxError) return; + // remove ?modal=xxxx from querystring + const newQueryParams = Object + .keys(this.props.query) + .filter((key) => key.substring(0, 5) !== 'modal') + .reduce( + (newObj, key) => { + newObj[key] = this.props.query[key]; + return newObj; + }, + {} + ); + + navigate(newQueryParams); + } + + render() { + const query = this.props.query; + const action = query.action || 'index'; + const mainComponent = actions[action] || NotFoundPage; + const modalComponent = Votr.ajaxError ? ErrorModal : modalActions[query.modal]; + + const C = mainComponent; + + return ( +
    + + + + +
    + ); + } +} + +App.propTypes = { + query: PropTypes.object.isRequired, +}; diff --git a/votrfront/js/src/ajax.js b/votrfront/js/src/ajax.js new file mode 100644 index 0000000..eab18df --- /dev/null +++ b/votrfront/js/src/ajax.js @@ -0,0 +1,165 @@ +import React, { Component } from 'react'; +import $ from 'jquery'; + +const debug = function(...args) { + if (process.env.NODE_ENV !== 'production') { + // eslint-disable-next-line + console.log(...args); + } +}; + +export function sendRpc(name, args, callback) { + const HEADER_LENGTH = 10; + let processed = 0; + let result; + let finished = false; + const xhr = new XMLHttpRequest(); + + function update() { + if (finished) return; + while (true) { + const waiting = xhr.responseText.length - processed; + if (waiting < HEADER_LENGTH) { + break; + } + const header = xhr.responseText.substr(processed, HEADER_LENGTH); + const length = parseInt(header, HEADER_LENGTH); + if (waiting < HEADER_LENGTH + length) { + break; + } + const payload = xhr.responseText.substr(processed + HEADER_LENGTH, length); + const data = JSON.parse(payload); + debug('RECEIVED', data); + if (data.log !== undefined) { + logs.push(data); + } + if (data.result !== undefined) { + result = data.result; + } + if (data.error !== undefined) { + return fail(data.error); + } + processed += HEADER_LENGTH + length; + } + if (xhr.readyState === 4) { + if (processed !== xhr.responseText.length || result === undefined) { + debug('INCOMPLETE!'); + return fail('Network error: Incomplete response'); + } + finished = true; + if (callback) { + callback(result); + } + } + Votr.appRoot.forceUpdate(); + } + + function fail(e) { + if (finished) return; + finished = true; + debug('FAILED!', e); + if (!Votr.ajaxError) { + Votr.ajaxError = (typeof e === 'string' || e instanceof String) ? e : 'Network error'; + Votr.appRoot.forceUpdate(); + } + } + + xhr.onload = update; + xhr.onprogress = update; + xhr.onerror = fail; + xhr.open('POST', 'rpc?name=' + name, true); + xhr.setRequestHeader('Content-Type', 'application/json'); + xhr.setRequestHeader('X-CSRF-Token', Votr.settings.csrf_token); + xhr.send(JSON.stringify(args)); +} + +Votr.ajaxError = null; + +export const logs = []; + +export const RequestCache = {}; + +RequestCache.pending = {}; + +RequestCache.sendRequest = function(request) { + const cacheKey = request.join('\0'); + if (RequestCache[cacheKey]) { + return; + } + if (RequestCache.pending[cacheKey]) { + return; + } + RequestCache.pending[cacheKey] = true; + sendRpc(request[0], request.slice(1), (result) => { + RequestCache[cacheKey] = result; + }); +}; + +RequestCache.invalidate = function(command) { + for (let key in RequestCache) { + if (key.split('\0')[0] === command) { + delete RequestCache[key]; + } + } + + for (let key in RequestCache.pending) { + if (key.split('\0')[0] === command) { + delete RequestCache.pending[key]; + } + } +}; + +export function CacheRequester() { + this.missing = []; + this.loadedAll = true; +}; + +CacheRequester.prototype.get = function(...request) { + const cacheKey = request.join('\0'); + if (RequestCache[cacheKey] !== undefined) { + return RequestCache[cacheKey]; + } else { + this.missing.push(request); + this.loadedAll = false; + return null; + } +}; + +export class Loading extends Component { + componentDidMount() { + if (this.props.requests) { + this.props.requests.forEach( + (request) => {RequestCache.sendRequest(request);} + ); + } + } + + componentDidUpdate() { + if (this.props.requests) { + this.props.requests.forEach( + (request) => {RequestCache.sendRequest(request);} + ); + } + } + + render() { + return Načítavam...; + } +} + + +export const goPost = (url) => { + $('
    ', { method: 'POST', action: url, appendTo: 'body' }).submit(); +}; + +export const goLogout = () => { + goPost('logout'); +}; + +export const goReset = () => { + goPost('reset?destination=' + encodeURIComponent(location.search)); +}; + +export const goResetHome = () => { + goPost('reset?destination='); +}; diff --git a/votrfront/js/src/coursesStats.js b/votrfront/js/src/coursesStats.js new file mode 100644 index 0000000..3528ad1 --- /dev/null +++ b/votrfront/js/src/coursesStats.js @@ -0,0 +1,86 @@ +import React from 'react'; + +const ZNAMKY = { + A: 1, + B: 1.5, + C: 2, + D: 2.5, + E: 3, + F: 4, +}; + +export const coursesStats = (hodnotenia) => { + const result = {}; + + result.zima = {}; + result.zima.count = 0; + result.zima.creditsCount = 0; + + result.leto = {}; + result.leto.count = 0; + result.leto.creditsCount = 0; + + result.spolu = {}; + result.spolu.count = hodnotenia.length; + result.spolu.creditsCount = 0; + + hodnotenia.forEach((row) => { + let credits = parseInt(row.kredit, 10); + if (row.hodn_znamka && row.hodn_znamka[0] === 'F') { + credits = 0; + } + result.spolu.creditsCount += credits; + if (row.semester === 'Z') { + result.zima.count += 1; + result.zima.creditsCount += credits; + } + if (row.semester === 'L') { + result.leto.count += 1; + result.leto.creditsCount += credits; + } + }); + + return result; +}; + +export const weightedStudyAverage = (hodnotenia) => { + let weightedSum = 0; + let creditsSum = 0; + + hodnotenia.forEach((row) => { + const value = ZNAMKY[row.hodn_znamka[0]]; + if (value) { + weightedSum += value * parseInt(row.kredit, 10); + creditsSum += parseInt(row.kredit, 10); + } + }); + + if (creditsSum === 0) { + return null; + } + return weightedSum / creditsSum; +}; + +export const renderWeightedStudyAverage = (hodnotenia) => { + const average = weightedStudyAverage(hodnotenia); + if (average === null) { + return null; + } + return ( + + {average.toFixed(2)} + + ); +}; + +export const currentAcademicYear = () => { + const date = new Date(); + const year = date.getFullYear(); + const month = date.getMonth() + 1; + + if (month < 8) { + return (year - 1) + '/' + year; + } else { + return year + '/' + (year + 1); + } +}; diff --git a/votrfront/js/src/humanizeAISData.js b/votrfront/js/src/humanizeAISData.js new file mode 100644 index 0000000..91454ac --- /dev/null +++ b/votrfront/js/src/humanizeAISData.js @@ -0,0 +1,47 @@ +const humanizeWith = (table) => { + return (value) => { + return table[value] || value; + }; +}; + +export const humanizeTypVyucby = humanizeWith({ + A: 'povinné (A)', + B: 'povinne voliteľné (B)', + C: 'výberové (C)', +}); + +export const humanizeTerminHodnotenia = humanizeWith({ + 'R - Riadny termín': 'riadny', + '1 - Prvý opravný termín': 'prvý opravný', + '2 - Druhý opravný termín': 'druhý opravný', +}); + +export const humanizeNazovPriemeru = humanizeWith({ + 'Sem ?': 'Semester', + 'AkadR ?': 'Akademický rok', +}); + +export const humanizeBoolean = humanizeWith({ + A: 'áno', + N: 'nie', +}); + +export const classForSemester = (semester) => { + if (semester === 'Z') { + return 'zima'; + } + if (semester === 'L') { + return 'leto'; + } + return undefined; +}; + +export const plural = (count, one, few, many) => { + if (count === 1) { + return one; + } + if (count >= 2 && count <= 4) { + return few; + } + return many; +}; diff --git a/votrfront/js/src/layout.js b/votrfront/js/src/layout.js new file mode 100644 index 0000000..d3c99fd --- /dev/null +++ b/votrfront/js/src/layout.js @@ -0,0 +1,243 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import $ from 'jquery'; + +import { CacheRequester, Loading, goLogout, goReset, logs } from './ajax'; +import { FakeLink, Link } from './router'; + +export class PageLayout extends Component { + render() { + return ( +
    + +
    +
    + +
    +
    +
    + {this.props.children} +
    +
    +
    +
    + ); + } +} + +PageLayout.propTypes = { + query: PropTypes.object.isRequired, +}; + +export class PageNavbar extends Component { + render() { + return ( +
    +
    +
    + Votr +
    +
    + +
    +
    +
      +
    • O aplikácii
    • +
    • Obnoviť
    • +
    • Odhlásiť
    • +
    +
    +
    +
    + ); + } +} + +export class LogStatus extends Component { + render() { + const entry = logs[logs.length - 1]; + let message; + if (!entry) { + message = '\xA0'; // nbsp + } else if (entry.log === 'http' && entry.message.match(/^Requesting/)) { + message = 'Čakám na AIS...'; + } else if (entry.log === 'rpc' && entry.message.match(/finished$/)) { + message = '\xA0'; // nbsp + } else { + message = `Spracovávam dáta... (${entry.message}")`; + } + return ( +

    + {message} +

    + ); + } +} + +export class PageTitle extends Component { + componentDidMount() { + document.title = this.refs.title.textContent; + } + + componentDidUpdate() { + document.title = this.refs.title.textContent; + } + + render() { + return

    {this.props.children}

    ; + } +} + +export class MainMenu extends Component { + + renderMenuItem(content, href, moreActions) { + const isActive = href.action === this.props.query.action + || (moreActions && moreActions[this.props.query.action]); + return ( +
  • + {content} +
  • + ); + } + + renderDisabled(content) { + return
  • {content}
  • ; + } + + render() { + const { studiumKey, zapisnyListKey } = this.props.query; + + const cache = new CacheRequester(); + const somStudent = cache.get('get_som_student'); + + return ( +
      +
    • Moje štúdium
    • + + {!somStudent && (
    • Nie ste študentom.
    • )} + {somStudent && this.renderMenuItem('Moje predmety', { action: 'mojePredmety', zapisnyListKey })} + {somStudent && this.renderMenuItem('Moje skúšky', { action: 'mojeSkusky', zapisnyListKey })} + {somStudent && this.renderMenuItem('Moje hodnotenia', { action: 'mojeHodnotenia', studiumKey })} + {somStudent && this.renderMenuItem( + 'Priebežné hodnotenia', + { action: 'priebezneHodnotenia', zapisnyListKey } + )} + {/*somStudent && this.renderDisabled('Môj rozvrh')*/} + {somStudent && this.renderMenuItem( + 'Zápis predmetov', + { action: 'zapisZPlanu', zapisnyListKey }, { zapisZPonuky: true } + )} + {somStudent && this.renderMenuItem('Prehľad štúdia', { action: 'prehladStudia' })} + {!cache.loadedAll && (
    • )} +

    • +
    • Registre
    • + {this.renderMenuItem('Register osôb', { action: 'registerOsob' })} + {this.renderMenuItem('Register predmetov', { action: 'registerPredmetov' })} + {/*this.renderDisabled('Register miestností')*/} + {/*this.renderDisabled('Register študijných programov')*/} +
    + ); + } +}; + +MainMenu.propTypes = { + query: PropTypes.object.isRequired, +}; + +export class FormItem extends Component { + render() { + if (this.props.label) { + return ( + + ); + } else { + return ( +
    +
    {this.props.children}
    +
    + ); + } + } +} + +export class ModalBase extends Component { + + componentDidMount() { + const $node = $(this.refs.modal); + $node.modal(); + $node.on('hide.bs.modal', (e) => { + if ($node.attr('data-show') === 'true') { + e.preventDefault(); + this.props.onClose(); + } + }); + } + + componentDidUpdate() { + const $node = $(this.refs.modal); + $node.modal($node.attr('data-show') === 'true' ? 'show' : 'hide'); + } + + render() { + const C = this.props.component; + + return ( + + ); + } +} + +ModalBase.propTypes = { + component: PropTypes.func, + onClose: PropTypes.func.isRequired, + query: PropTypes.object.isRequired, +}; + +// TODO Refactor all modals to use something like react-bootstrap +// so that the files in libs/ are not required + +export class Modal extends Component { + + render() { + return ( +
    +
    + {this.props.closeButton && + } +

    {this.props.title}

    +
    +
    + {this.props.children} +
    + {this.props.footer} +
    + ); + } +} + +Modal.propTypes = { + closeButton: PropTypes.bool.isRequired, + title: PropTypes.node.isRequired, + footer: PropTypes.node, +}; + +Modal.defaultProps = { + closeButton: true, +}; diff --git a/votrfront/js/src/ovce.js b/votrfront/js/src/ovce.js new file mode 100644 index 0000000..84686a7 --- /dev/null +++ b/votrfront/js/src/ovce.js @@ -0,0 +1,89 @@ +import $ from 'jquery'; + +const cookieDurationClose = 3; +const cookieDurationVote = 60; +const cookieName = 'ovcaKolacik'; +const cookieValue = 'on'; +// Starting this day the cookie won't be visible +const cookieHideDate = Date.parse('6 Jul 2017'); + +const createDiv = () => { + const bodytag = document.getElementsByTagName('body')[0]; + const div = document.createElement('div'); + div.setAttribute('id', 'cookie-ovca'); + div.innerHTML = ''; + div.innerHTML += ''; + + // Adds the Cookie Law Banner just after the opening tag + bodytag.insertBefore(div, bodytag.firstChild); + + // Adds a class tothe tag when the banner is visible + document.getElementsByTagName('body')[0].className += ' cookiebanner'; +}; + +const createCookie = (name, value, days) => { + let expires = ''; + if (days) { + const date = new Date(); + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + expires = '; expires=' + date.toGMTString(); + } + document.cookie = name + '=' + value + expires + '; path=/'; +}; + +const checkCookie = (name) => { + const nameEQ = name + '='; + const ca = document.cookie.split(';'); + for (let i = 0; i < ca.length; i++) { + let c = ca[i]; + while (c.charAt(0) === ' ') { + c = c.substring(1, c.length); + } + if (c.indexOf(nameEQ) === 0) { + return c.substring(nameEQ.length, c.length); + } + } + return null; +}; + +const eraseCookie = (name) => { + createCookie(name, '', -1); +}; + +const removeMe = (duration) => { + const element = document.getElementById('cookie-ovca'); + element.parentNode.removeChild(element); + createCookie(window.cookieName, window.cookieValue, duration); +}; + +const isFromFMFI = (callback) => { + $.ajax({ + type: 'POST', + url: '/rpc?name=get_studia', + data: [], + success: (msg) => { + if (msg.match(/"organizacna_jednotka": "FMFI"/) !== null) { + callback(); + } + }, + beforeSend: (req) => { + req.setRequestHeader('X-CSRF-Token', Votr.settings.csrf_token); + req.setRequestHeader('Content-Type', 'application/json'); + }, + }); +}; + +const checkDOMChange = () => { + if ($('.main-menu li').size() >= 11) { + const today = new Date(); + if ((checkCookie(window.cookieName) !== window.cookieValue) && (cookieHideDate > today)) { + isFromFMFI(createDiv); + } + } else { + setTimeout(checkDOMChange, 100); + } +}; + +$(document).ready(() => { + checkDOMChange(); +}); diff --git a/votrfront/js/prologue.js b/votrfront/js/src/prologue.js similarity index 80% rename from votrfront/js/prologue.js rename to votrfront/js/src/prologue.js index 15ef792..bb062d0 100644 --- a/votrfront/js/prologue.js +++ b/votrfront/js/src/prologue.js @@ -1,8 +1,7 @@ - -Votr.setDebug = function (enabled) { +Votr.setDebug = (enabled) => { document.cookie = enabled ? 'votr_debug=true' : 'votr_debug='; location.reload(); -} +}; if (!history.pushState) { document.getElementById('votr').innerHTML = ` @@ -10,7 +9,9 @@ if (!history.pushState) {

    Votr

    Votr ponúka študentom jednoduchší a pohodlnejší spôsob, ako robiť najčastejšie činnosti zo systému AIS.

    Váš prehliadač je príliš starý a nedokáže robiť všetko to, čo Votr potrebuje.

    -

    Prosím stiahnite si novší prehliadač. Nové prehliadače sú rýchlejšie, pohodlnejšie a navyše bezpečnejšie.

    +

    + Prosím stiahnite si novší prehliadač. Nové prehliadače sú rýchlejšie, pohodlnejšie a navyše bezpečnejšie. +


    `; - if (window.ga) ga('send', 'pageview'); + if (window.ga) { + ga('send', 'pageview'); + } } diff --git a/votrfront/js/router.js b/votrfront/js/src/router.js similarity index 50% rename from votrfront/js/router.js rename to votrfront/js/src/router.js index 858fa78..fcf17bd 100644 --- a/votrfront/js/router.js +++ b/votrfront/js/src/router.js @@ -1,55 +1,56 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import $ from 'jquery'; export function trackPageView() { if (!window.ga) return; - var current = location.protocol + '//' + location.hostname + + const current = location.protocol + '//' + location.hostname + location.pathname + location.search; - if (current == trackPageView.last) return; + if (current === trackPageView.last) return; trackPageView.last = current; ga('send', 'pageview', { location: current }); }; -export var AnalyticsMixin = { +export const AnalyticsMixin = { componentDidMount() { trackPageView(); }, componentDidUpdate() { trackPageView(); - } + }, }; -function parseQueryString(queryString) { +const parseQueryString = (queryString) => { if (!queryString) return {}; - var result = {}; - var pairs = queryString.split('&'); - for (var i = 0; i < pairs.length; i++) { - var index = pairs[i].indexOf('='); - if (index == -1) { + const result = {}; + const pairs = queryString.split('&'); + for (let i = 0; i < pairs.length; i++) { + let index = pairs[i].indexOf('='); + if (index === -1) { index = pairs[i].length; } - var name = pairs[i].substring(0, index); - var value = pairs[i].substring(index + 1); + const name = pairs[i].substring(0, index); + const value = pairs[i].substring(index + 1); result[name] = decodeURIComponent(value.replace(/\+/g, ' ')); } return result; -} - +}; -export var Root = React.createClass({ - mixins: [AnalyticsMixin], +export class Root extends Component { - handlePopState() { + handlePopState = () => { this.forceUpdate(); - }, + } componentDidMount() { window.addEventListener('popstate', this.handlePopState, false); - }, + } render() { - var queryString = location.search.substring(1); + const queryString = location.search.substring(1); if (queryString !== this.lastQueryString) { this.query = parseQueryString(queryString); this.lastQueryString = queryString; @@ -57,59 +58,85 @@ export var Root = React.createClass({ return ; } -}); +} +Root.mixins = [AnalyticsMixin]; -export function buildUrl(href) { - if (_.isString(href)) return href; - return '?' + $.param(_.omit(href, _.isUndefined), true); +export const buildUrl = (href) => { + if (typeof href === 'string' || href instanceof String) { + return href; + } + // remove empty query paramaters + const newHref = Object.keys(href) + .filter((key) => key !== undefined) + .reduce( + (newObj, key) => { + newObj[key] = href[key]; + return newObj; + }, + {} + ); + + return '?' + $.param(newHref, true); }; - -export function navigate(href) { +export const navigate = (href) => { Votr.didNavigate = true; history.pushState(null, '', Votr.settings.url_root + buildUrl(href)); Votr.appRoot.forceUpdate(); }; - -export var Link = React.createClass({ - handleClick(event) { +export class Link extends Component { + handleClick = (event) => { // Chrome fires onclick on middle click. Firefox only fires it on document, // see , // but React adds event listeners to document so we still see a click event. - if (event.button != 0) return; + if (event.button !== 0) { + return; + } event.preventDefault(); navigate(this.props.href); - }, + } render() { - return ; + return ( + + ); } -}); +} // Looks and acts like a link, but doesn't have a href and cannot be opened in // a new tab when middle-clicked or ctrl-clicked. -export var FakeLink = React.createClass({ - propTypes: { - onClick: React.PropTypes.func.isRequired - }, +export class FakeLink extends Component { // Pressing Enter on emits a click event, and the HTML5 spec // says elements with tabindex should do that too, but they don't. // suggests using a keyup event: - handleKeyUp(event) { - if (event.which == 13) { + handleKeyUp = (event) => { + if (event.which === 13) { event.preventDefault(); this.props.onClick(event); } - }, + } render() { - return ; + return ( + + ); } -}); +} + +FakeLink.propTypes = { + onClick: PropTypes.func.isRequired, +}; diff --git a/votrfront/js/src/sorting.js b/votrfront/js/src/sorting.js new file mode 100644 index 0000000..7ae933d --- /dev/null +++ b/votrfront/js/src/sorting.js @@ -0,0 +1,115 @@ +import React from 'react'; + +import { navigate } from './router'; + +export const sortAs = {}; + +sortAs.personName = (text) => { + let words = text.replace(/,/g, '').split(' '); + words = words.filter((word) => !word.match(/\.$/)); + // last name goes to the beginning + words.unshift(words.pop()); + return words.join(' ').toLowerCase(); + // TODO: consider using latinise (see fajr). +}; + + +sortAs.number = (text) => { + return +text.replace(/,/g, '.'); + // TODO: this won't be needed when fladgejt starts returning numbers +}; + + +sortAs.date = (date) => { + if (date.match(/^\d\d\.\d\d\.\d\d\d\d/)) { + return date.substring(6, 10) + date.substring(3, 5) + date.substring(0, 2) + date.substring(10); + } + return date; +}; + + +sortAs.interval = (text) => { + const index = text.indexOf('do '); + if (index === -1) { + return ''; + } + return sortAs.date(text.substring(index + 3)); +}; + +export const sortTable = (items, columns, query, queryKey) => { + const orderString = query[queryKey] || columns.defaultOrder; + const order = orderString ? orderString.split(/(?=[ad])/) : []; + const orderLength = order.length; + const orderAsc = order.map((orderItem) => orderItem.substring(0, 1) === 'a'); + const orderColumns = order.map((orderItem) => columns[orderItem.substring(1)]); + + items = items.map((item, index) => { + const criteria = []; + for (let i = 0; i < orderLength; i++) { + const [label, prop, process, preferDesc] = orderColumns[i]; + let value = prop ? item[prop] : item; + if (process) { + value = process(value); + } + if (!prop && !process) { + value = undefined; + } + criteria.push(value); + } + return { item, index, criteria }; + }); + + items.sort((a, b) => { + for (let i = 0; i < orderLength; i++) { + const ac = a.criteria[i], bc = b.criteria[i]; + if (ac === bc) { + continue; + } + if (ac < bc) { + return orderAsc[i] ? -1 : 1; + } + if (ac > bc) { + return orderAsc[i] ? 1 : -1; + } + } + return a.index - b.index; + }); + + items = items.map((a) => a.item); + + const handleClick = (event) => { + const index = event.currentTarget.getAttribute('data-index'); + const [label, prop, process, preferDesc] = columns[index]; + + const newOrder = order.filter( + (ord) => ord !== 'a' + index && ord !== 'd' + index + ); + newOrder.unshift(( + order[0] === 'a' + index ? 'd' : + order[0] === 'd' + index ? 'a' : + preferDesc ? 'd' : 'a' + ) + index); + + navigate({ ...query, [queryKey]: newOrder.join('') }); + }; + + const header = ( + + {columns.map(([label, prop, process, preferDesc], index) => ( + + {label} + + ))} + + ); + + return [items, header]; +}; diff --git a/votrfront/js/src/utils.js b/votrfront/js/src/utils.js new file mode 100644 index 0000000..e69de29 diff --git a/votrfront/js/webpack.common.js b/votrfront/js/webpack.common.js new file mode 100644 index 0000000..bf1ebc4 --- /dev/null +++ b/votrfront/js/webpack.common.js @@ -0,0 +1,38 @@ +const path = require('path'); +const webpack = require('webpack'); +const LodashModuleReplacementPlugin = require('lodash-webpack-plugin'); +const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; + +module.exports = { + entry: { + app: './main.js', + }, + module: { + rules: [ + { + test: /\.js$/, + exclude: /(node_modules|bower_components)/, + use: { + loader: 'babel-loader', + }, + }, + ], + }, + plugins: [ + new LodashModuleReplacementPlugin({ + shorthands: true, + }), + // remove the ProvidePlugin when libs/ folder is purged + new webpack.ProvidePlugin({ + $: 'jquery', + jQuery: 'jquery', + }), + new BundleAnalyzerPlugin({ + openAnalyzer: false, + }), + ], + output: { + filename: 'votr.bundle.js', + path: path.join(__dirname, '../static'), + }, +}; diff --git a/votrfront/js/webpack.dev.js b/votrfront/js/webpack.dev.js new file mode 100644 index 0000000..e5909c3 --- /dev/null +++ b/votrfront/js/webpack.dev.js @@ -0,0 +1,7 @@ +const merge = require('webpack-merge'); +const common = require('./webpack.common.js'); + +module.exports = merge(common, { + mode: 'development', + devtool: 'inline-source-map', +}); diff --git a/votrfront/js/webpack.prod.js b/votrfront/js/webpack.prod.js new file mode 100644 index 0000000..556b7cf --- /dev/null +++ b/votrfront/js/webpack.prod.js @@ -0,0 +1,16 @@ +const webpack = require('webpack'); +const merge = require('webpack-merge'); +const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); +const common = require('./webpack.common.js'); + +module.exports = merge(common, { + mode: 'production', + plugins: [ + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify('production'), + }), + new webpack.optimize.OccurrenceOrderPlugin(), + new webpack.optimize.ModuleConcatenationPlugin(), + new UglifyJSPlugin(), + ], +}); diff --git a/votrfront/js/yarn.lock b/votrfront/js/yarn.lock new file mode 100644 index 0000000..c6aa951 --- /dev/null +++ b/votrfront/js/yarn.lock @@ -0,0 +1,6034 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@7.0.0-beta.40", "@babel/code-frame@^7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz#37e2b0cf7c56026b4b21d3927cadf81adec32ac6" + dependencies: + "@babel/highlight" "7.0.0-beta.40" + +"@babel/core@^7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0-beta.40.tgz#455464dd81d499fd97d32b473f0331f74379a33f" + dependencies: + "@babel/code-frame" "7.0.0-beta.40" + "@babel/generator" "7.0.0-beta.40" + "@babel/helpers" "7.0.0-beta.40" + "@babel/template" "7.0.0-beta.40" + "@babel/traverse" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + babylon "7.0.0-beta.40" + convert-source-map "^1.1.0" + debug "^3.0.1" + json5 "^0.5.0" + lodash "^4.2.0" + micromatch "^2.3.11" + resolve "^1.3.2" + source-map "^0.5.0" + +"@babel/generator@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.40.tgz#ab61f9556f4f71dbd1138949c795bb9a21e302ea" + dependencies: + "@babel/types" "7.0.0-beta.40" + jsesc "^2.5.1" + lodash "^4.2.0" + source-map "^0.5.0" + trim-right "^1.0.1" + +"@babel/helper-annotate-as-pure@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0-beta.40.tgz#095dd4c70b231eba17ebf61c3434e6f9d71bd574" + dependencies: + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-builder-binary-assignment-operator-visitor@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.0.0-beta.40.tgz#bec4240c95d8b646812c5d4ac536a5579dbcdd53" + dependencies: + "@babel/helper-explode-assignable-expression" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-builder-react-jsx@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.0.0-beta.40.tgz#2a171b6c4939c6cd0bdc38cca261d1f3b32cedb1" + dependencies: + "@babel/types" "7.0.0-beta.40" + esutils "^2.0.0" + +"@babel/helper-call-delegate@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.0.0-beta.40.tgz#5d5000d0bf76c68ee6866961e0b7eb6e9ed52438" + dependencies: + "@babel/helper-hoist-variables" "7.0.0-beta.40" + "@babel/traverse" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-define-map@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.0.0-beta.40.tgz#ad64c548dd98e7746305852f113ed04dc74329c0" + dependencies: + "@babel/helper-function-name" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + lodash "^4.2.0" + +"@babel/helper-explode-assignable-expression@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.0.0-beta.40.tgz#0ef579288d894a987c60bf0577c074ad18cfa9dd" + dependencies: + "@babel/traverse" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-function-name@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz#9d033341ab16517f40d43a73f2d81fc431ccd7b6" + dependencies: + "@babel/helper-get-function-arity" "7.0.0-beta.40" + "@babel/template" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-get-function-arity@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz#ac0419cf067b0ec16453e1274f03878195791c6e" + dependencies: + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-hoist-variables@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0-beta.40.tgz#59d47fd133782d60db89af0d18083ad3c9f4801c" + dependencies: + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-module-imports@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.40.tgz#251cbb6404599282e8f7356a5b32c9381bef5d2d" + dependencies: + "@babel/types" "7.0.0-beta.40" + lodash "^4.2.0" + +"@babel/helper-module-transforms@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.0.0-beta.40.tgz#e5240afd47bd98f6ae65874b9ae508533abfee76" + dependencies: + "@babel/helper-module-imports" "7.0.0-beta.40" + "@babel/helper-simple-access" "7.0.0-beta.40" + "@babel/template" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + lodash "^4.2.0" + +"@babel/helper-optimise-call-expression@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0-beta.40.tgz#f0e7f70d455bff8ab6a248a84f0221098fa468ac" + dependencies: + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-regex@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0-beta.40.tgz#b47018ecca8ff66bb390c34a95ff71bc01495833" + dependencies: + lodash "^4.2.0" + +"@babel/helper-remap-async-to-generator@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0-beta.40.tgz#33414d1cc160ebf0991ebc60afebe36b08feae05" + dependencies: + "@babel/helper-annotate-as-pure" "7.0.0-beta.40" + "@babel/helper-wrap-function" "7.0.0-beta.40" + "@babel/template" "7.0.0-beta.40" + "@babel/traverse" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-replace-supers@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0-beta.40.tgz#2ab0c9e7fa17d313745f1634ce6b7bccaa5dd5fe" + dependencies: + "@babel/helper-optimise-call-expression" "7.0.0-beta.40" + "@babel/template" "7.0.0-beta.40" + "@babel/traverse" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-simple-access@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.0.0-beta.40.tgz#018f765090a3d25153778958969f235dc6ce5b57" + dependencies: + "@babel/template" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + lodash "^4.2.0" + +"@babel/helper-wrap-function@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0-beta.40.tgz#4db4630cdaf4fd47fa2c45b5b7a9ecc33ff3f2be" + dependencies: + "@babel/helper-function-name" "7.0.0-beta.40" + "@babel/template" "7.0.0-beta.40" + "@babel/traverse" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + +"@babel/helpers@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.0.0-beta.40.tgz#82f8e144f56b2896b1d624ca88ac4603023ececd" + dependencies: + "@babel/template" "7.0.0-beta.40" + "@babel/traverse" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + +"@babel/highlight@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.40.tgz#b43d67d76bf46e1d10d227f68cddcd263786b255" + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +"@babel/plugin-proposal-async-generator-functions@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.0.0-beta.40.tgz#64f4aebc3fff33d2ae8f0a0870f0dfe2ff6815d6" + dependencies: + "@babel/helper-remap-async-to-generator" "7.0.0-beta.40" + "@babel/plugin-syntax-async-generators" "7.0.0-beta.40" + +"@babel/plugin-proposal-class-properties@^7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.0.0-beta.40.tgz#ee0549729e9f44603efa17523b459ea3021458dc" + dependencies: + "@babel/helper-function-name" "7.0.0-beta.40" + "@babel/plugin-syntax-class-properties" "7.0.0-beta.40" + +"@babel/plugin-proposal-object-rest-spread@7.0.0-beta.40", "@babel/plugin-proposal-object-rest-spread@^7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-beta.40.tgz#ce35d2240908e52706a612eb26d67db667cd700f" + dependencies: + "@babel/plugin-syntax-object-rest-spread" "7.0.0-beta.40" + +"@babel/plugin-proposal-optional-catch-binding@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0-beta.40.tgz#e76ddcb21880eea0225f1dcde20a5e97ca85fd39" + dependencies: + "@babel/plugin-syntax-optional-catch-binding" "7.0.0-beta.40" + +"@babel/plugin-proposal-unicode-property-regex@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0-beta.40.tgz#1fb2c29c8bd88d5fff82ec080dbe24e7126ec460" + dependencies: + "@babel/helper-regex" "7.0.0-beta.40" + regexpu-core "^4.1.3" + +"@babel/plugin-syntax-async-generators@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0-beta.40.tgz#6c45889569add3b3721cc9a481ae99906f240874" + +"@babel/plugin-syntax-class-properties@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0-beta.40.tgz#ff82c04c6d97cdb947dc64e3f3d4bc791e85a16f" + +"@babel/plugin-syntax-jsx@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0-beta.40.tgz#db44d52ff06f784be22f2659e694cc2cf97f99f9" + +"@babel/plugin-syntax-object-rest-spread@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0-beta.40.tgz#d5e04536062e4df685c203ae48bb19bfe2cf235c" + +"@babel/plugin-syntax-optional-catch-binding@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0-beta.40.tgz#2e3de0919d05136bb658172ef9ba9ef7e84bce9e" + +"@babel/plugin-transform-arrow-functions@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0-beta.40.tgz#0842045b16835d6da0c334d0b09d575852f27962" + +"@babel/plugin-transform-async-to-generator@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.0.0-beta.40.tgz#9195e2473a435b9a9aabc0b64572e9d1ec1c57cb" + dependencies: + "@babel/helper-module-imports" "7.0.0-beta.40" + "@babel/helper-remap-async-to-generator" "7.0.0-beta.40" + +"@babel/plugin-transform-block-scoped-functions@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0-beta.40.tgz#491e61f860cabe69379233983fe7ca14f879e41f" + +"@babel/plugin-transform-block-scoping@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0-beta.40.tgz#23197ee6f696b7e5ace884f0dc5434df20d7dd97" + dependencies: + lodash "^4.2.0" + +"@babel/plugin-transform-classes@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.0.0-beta.40.tgz#c7a752009df4bb0f77179027daa0783f9a036b0b" + dependencies: + "@babel/helper-annotate-as-pure" "7.0.0-beta.40" + "@babel/helper-define-map" "7.0.0-beta.40" + "@babel/helper-function-name" "7.0.0-beta.40" + "@babel/helper-optimise-call-expression" "7.0.0-beta.40" + "@babel/helper-replace-supers" "7.0.0-beta.40" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0-beta.40.tgz#e4bd53455d9f96882cc8e9923895d71690f6969e" + +"@babel/plugin-transform-destructuring@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.0.0-beta.40.tgz#503a4719eb9ed8c933b50d4ec3f106ed371852ee" + +"@babel/plugin-transform-dotall-regex@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0-beta.40.tgz#89b5ccff477624b97129f9a7e262a436437d7ae2" + dependencies: + "@babel/helper-regex" "7.0.0-beta.40" + regexpu-core "^4.1.3" + +"@babel/plugin-transform-duplicate-keys@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0-beta.40.tgz#91599be229d4409cf3c9bbd094fb04d354bd8068" + +"@babel/plugin-transform-exponentiation-operator@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.0.0-beta.40.tgz#bf0bafdd5aad7061c25dba25e29e12329838baeb" + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "7.0.0-beta.40" + +"@babel/plugin-transform-for-of@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0-beta.40.tgz#67920d749bac4840ceeae9907d918dad33908244" + +"@babel/plugin-transform-function-name@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.0.0-beta.40.tgz#37b5ca4f90fba207d359c0be3af5bfecdc737a3d" + dependencies: + "@babel/helper-function-name" "7.0.0-beta.40" + +"@babel/plugin-transform-literals@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0-beta.40.tgz#a6bf8808f97accf42a171b27a133802aa0650d3e" + +"@babel/plugin-transform-modules-amd@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.0.0-beta.40.tgz#1882f1a02b16d261a332c87c035c9aeefd402683" + dependencies: + "@babel/helper-module-transforms" "7.0.0-beta.40" + +"@babel/plugin-transform-modules-commonjs@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.0.0-beta.40.tgz#a85f8c311f498a94a45531cc4ed5ff98b338a70a" + dependencies: + "@babel/helper-module-transforms" "7.0.0-beta.40" + "@babel/helper-simple-access" "7.0.0-beta.40" + +"@babel/plugin-transform-modules-systemjs@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.0.0-beta.40.tgz#808b372bdbe06a28bf7a3870d8e810bd7298227a" + dependencies: + "@babel/helper-hoist-variables" "7.0.0-beta.40" + +"@babel/plugin-transform-modules-umd@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.0.0-beta.40.tgz#5bd4e395a2673e687ed592608ad2fd4883a5a119" + dependencies: + "@babel/helper-module-transforms" "7.0.0-beta.40" + +"@babel/plugin-transform-new-target@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0-beta.40.tgz#ee52bb87fbf325ac054811ec739b25fbce97809e" + +"@babel/plugin-transform-object-super@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.0.0-beta.40.tgz#c64f9ba3587610d76c2edfdd8f507a59ea3ba63d" + dependencies: + "@babel/helper-replace-supers" "7.0.0-beta.40" + +"@babel/plugin-transform-parameters@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.0.0-beta.40.tgz#efa366fab0dcbd0221b46aa2662c324b4b414d1d" + dependencies: + "@babel/helper-call-delegate" "7.0.0-beta.40" + "@babel/helper-get-function-arity" "7.0.0-beta.40" + +"@babel/plugin-transform-react-display-name@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.0.0-beta.40.tgz#2e9aba5d74da8ecee00d6d4bf68c833955355e4c" + +"@babel/plugin-transform-react-jsx-self@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.0.0-beta.40.tgz#cbf0286ec9e52129840e16d1a173adb98e52fb97" + dependencies: + "@babel/plugin-syntax-jsx" "7.0.0-beta.40" + +"@babel/plugin-transform-react-jsx-source@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.0.0-beta.40.tgz#7e62fe33f3e46c7f0d81d187d9c9aa348daa6488" + dependencies: + "@babel/plugin-syntax-jsx" "7.0.0-beta.40" + +"@babel/plugin-transform-react-jsx@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.0.0-beta.40.tgz#93af0b0ef691cda86ab52d912b50f72eb538349d" + dependencies: + "@babel/helper-builder-react-jsx" "7.0.0-beta.40" + "@babel/plugin-syntax-jsx" "7.0.0-beta.40" + +"@babel/plugin-transform-regenerator@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0-beta.40.tgz#f8a89ce89a0fae8e9cdfc2f2768104811517374a" + dependencies: + regenerator-transform "^0.12.3" + +"@babel/plugin-transform-shorthand-properties@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0-beta.40.tgz#421835237b0fcab0e67c941726d95dfc543514f4" + +"@babel/plugin-transform-spread@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0-beta.40.tgz#881578938e5750137301750bef7fdd0e01be76be" + +"@babel/plugin-transform-sticky-regex@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0-beta.40.tgz#5b44b31f8539fc66af18962e55752b82298032ee" + dependencies: + "@babel/helper-regex" "7.0.0-beta.40" + +"@babel/plugin-transform-template-literals@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0-beta.40.tgz#5ef3377d1294aee39b913768a1f884806a45393b" + dependencies: + "@babel/helper-annotate-as-pure" "7.0.0-beta.40" + +"@babel/plugin-transform-typeof-symbol@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0-beta.40.tgz#67f0b8a5dd298b0aa5b347c3b6738c9c7baf1bcf" + +"@babel/plugin-transform-unicode-regex@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0-beta.40.tgz#a956187aad2965d7c095d64b1ae87eba10e0a2c6" + dependencies: + "@babel/helper-regex" "7.0.0-beta.40" + regexpu-core "^4.1.3" + +"@babel/preset-env@^7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.0.0-beta.40.tgz#713292f9e410f76b3f4301330756c89343c4b2e4" + dependencies: + "@babel/plugin-proposal-async-generator-functions" "7.0.0-beta.40" + "@babel/plugin-proposal-object-rest-spread" "7.0.0-beta.40" + "@babel/plugin-proposal-optional-catch-binding" "7.0.0-beta.40" + "@babel/plugin-proposal-unicode-property-regex" "7.0.0-beta.40" + "@babel/plugin-syntax-async-generators" "7.0.0-beta.40" + "@babel/plugin-syntax-object-rest-spread" "7.0.0-beta.40" + "@babel/plugin-syntax-optional-catch-binding" "7.0.0-beta.40" + "@babel/plugin-transform-arrow-functions" "7.0.0-beta.40" + "@babel/plugin-transform-async-to-generator" "7.0.0-beta.40" + "@babel/plugin-transform-block-scoped-functions" "7.0.0-beta.40" + "@babel/plugin-transform-block-scoping" "7.0.0-beta.40" + "@babel/plugin-transform-classes" "7.0.0-beta.40" + "@babel/plugin-transform-computed-properties" "7.0.0-beta.40" + "@babel/plugin-transform-destructuring" "7.0.0-beta.40" + "@babel/plugin-transform-dotall-regex" "7.0.0-beta.40" + "@babel/plugin-transform-duplicate-keys" "7.0.0-beta.40" + "@babel/plugin-transform-exponentiation-operator" "7.0.0-beta.40" + "@babel/plugin-transform-for-of" "7.0.0-beta.40" + "@babel/plugin-transform-function-name" "7.0.0-beta.40" + "@babel/plugin-transform-literals" "7.0.0-beta.40" + "@babel/plugin-transform-modules-amd" "7.0.0-beta.40" + "@babel/plugin-transform-modules-commonjs" "7.0.0-beta.40" + "@babel/plugin-transform-modules-systemjs" "7.0.0-beta.40" + "@babel/plugin-transform-modules-umd" "7.0.0-beta.40" + "@babel/plugin-transform-new-target" "7.0.0-beta.40" + "@babel/plugin-transform-object-super" "7.0.0-beta.40" + "@babel/plugin-transform-parameters" "7.0.0-beta.40" + "@babel/plugin-transform-regenerator" "7.0.0-beta.40" + "@babel/plugin-transform-shorthand-properties" "7.0.0-beta.40" + "@babel/plugin-transform-spread" "7.0.0-beta.40" + "@babel/plugin-transform-sticky-regex" "7.0.0-beta.40" + "@babel/plugin-transform-template-literals" "7.0.0-beta.40" + "@babel/plugin-transform-typeof-symbol" "7.0.0-beta.40" + "@babel/plugin-transform-unicode-regex" "7.0.0-beta.40" + browserslist "^3.0.0" + invariant "^2.2.2" + semver "^5.3.0" + +"@babel/preset-react@^7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.0.0-beta.40.tgz#ccc8f916b694c8ea4b4ccbd1584f873caf199557" + dependencies: + "@babel/plugin-syntax-jsx" "7.0.0-beta.40" + "@babel/plugin-transform-react-display-name" "7.0.0-beta.40" + "@babel/plugin-transform-react-jsx" "7.0.0-beta.40" + "@babel/plugin-transform-react-jsx-self" "7.0.0-beta.40" + "@babel/plugin-transform-react-jsx-source" "7.0.0-beta.40" + +"@babel/template@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.40.tgz#034988c6424eb5c3268fe6a608626de1f4410fc8" + dependencies: + "@babel/code-frame" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + babylon "7.0.0-beta.40" + lodash "^4.2.0" + +"@babel/traverse@7.0.0-beta.40", "@babel/traverse@^7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.40.tgz#d140e449b2e093ef9fe1a2eecc28421ffb4e521e" + dependencies: + "@babel/code-frame" "7.0.0-beta.40" + "@babel/generator" "7.0.0-beta.40" + "@babel/helper-function-name" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + babylon "7.0.0-beta.40" + debug "^3.0.1" + globals "^11.1.0" + invariant "^2.2.0" + lodash "^4.2.0" + +"@babel/types@7.0.0-beta.40", "@babel/types@^7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.40.tgz#25c3d7aae14126abe05fcb098c65a66b6d6b8c14" + dependencies: + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^2.0.0" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + +accepts@~1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" + dependencies: + mime-types "~2.1.18" + negotiator "0.6.1" + +acorn-dynamic-import@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" + dependencies: + acorn "^5.0.0" + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + dependencies: + acorn "^3.0.4" + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + +acorn@^5.0.0, acorn@^5.3.0, acorn@^5.4.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.0.tgz#1abb587fbf051f94e3de20e6b26ef910b1828298" + +ajv-keywords@^3.0.0, ajv-keywords@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.1.0.tgz#ac2b27939c543e95d2c06e7f7f5c27be4aa543be" + +ajv@^4.9.1: + version "4.11.8" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + +ajv@^5.3.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +ajv@^6.0.1, ajv@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.2.0.tgz#afac295bbaa0152449e522742e4547c1ae9328d2" + dependencies: + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +ansi-escapes@^1.0.0, ansi-escapes@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + +ansi-escapes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" + dependencies: + color-convert "^1.9.0" + +ansi-styles@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + +are-we-there-yet@~1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + dependencies: + sprintf-js "~1.0.2" + +argv@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/argv/-/argv-0.0.2.tgz#ecbd16f8949b157183711b1bda334f37840185ab" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + +array-includes@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.7.0" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +assert@^1.1.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + dependencies: + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + +ast-types@0.10.1: + version "0.10.1" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.10.1.tgz#f52fca9715579a14f841d67d7f8d25432ab6a3dd" + +ast-types@0.10.2: + version "0.10.2" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.10.2.tgz#aef76a04fde54634976fc94defaad1a67e2eadb0" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + +async@^1.5.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +async@^2.0.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" + dependencies: + lodash "^4.14.0" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +atob@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.0.3.tgz#19c7a760473774468f20b2d2d03372ad7d4cbf5d" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +aws4@^1.2.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.0" + debug "^2.6.8" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.7" + slash "^1.0.0" + source-map "^0.5.6" + +babel-eslint@^8.2.2: + version "8.2.2" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.2.tgz#1102273354c6f0b29b4ea28a65f97d122296b68b" + dependencies: + "@babel/code-frame" "^7.0.0-beta.40" + "@babel/traverse" "^7.0.0-beta.40" + "@babel/types" "^7.0.0-beta.40" + babylon "^7.0.0-beta.40" + eslint-scope "~3.7.1" + eslint-visitor-keys "^1.0.0" + +babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helper-bindify-decorators@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz#14c19e5f142d7b47f19a52431e52b1ccbc40a330" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-explode-class@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb" + dependencies: + babel-helper-bindify-decorators "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-module-imports@^7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-helper-module-imports/-/babel-helper-module-imports-7.0.0-beta.3.tgz#e15764e3af9c8e11810c09f78f498a2bdc71585a" + dependencies: + babel-types "7.0.0-beta.3" + lodash "^4.2.0" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-loader@8.0.0-beta.2: + version "8.0.0-beta.2" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.0-beta.2.tgz#4d5b67c964dc8c9cba866fd13d6b90df3acf8723" + dependencies: + find-cache-dir "^1.0.0" + loader-utils "^1.0.2" + mkdirp "^0.5.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-lodash@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/babel-plugin-lodash/-/babel-plugin-lodash-3.3.2.tgz#da3a5b49ba27447f54463f6c4fa81396ccdd463f" + dependencies: + babel-helper-module-imports "^7.0.0-beta.3" + babel-types "^6.26.0" + glob "^7.1.1" + lodash "^4.17.4" + require-package-name "^2.0.1" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-async-generators@^6.5.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" + +babel-plugin-syntax-class-constructor-call@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz#9cb9d39fe43c8600bec8146456ddcbd4e1a76416" + +babel-plugin-syntax-class-properties@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" + +babel-plugin-syntax-decorators@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" + +babel-plugin-syntax-dynamic-import@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + +babel-plugin-syntax-export-extensions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz#70a1484f0f9089a4e84ad44bac353c95b9b12721" + +babel-plugin-syntax-flow@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" + +babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + +babel-plugin-transform-async-generator-functions@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-generators "^6.5.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-class-constructor-call@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz#80dc285505ac067dcb8d6c65e2f6f11ab7765ef9" + dependencies: + babel-plugin-syntax-class-constructor-call "^6.18.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-class-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" + dependencies: + babel-helper-function-name "^6.24.1" + babel-plugin-syntax-class-properties "^6.8.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-decorators@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz#788013d8f8c6b5222bdf7b344390dfd77569e24d" + dependencies: + babel-helper-explode-class "^6.24.1" + babel-plugin-syntax-decorators "^6.13.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-export-extensions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz#53738b47e75e8218589eea946cbbd39109bbe653" + dependencies: + babel-plugin-syntax-export-extensions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-flow-strip-types@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" + dependencies: + babel-plugin-syntax-flow "^6.18.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-object-rest-spread@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.26.0" + +babel-plugin-transform-regenerator@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-preset-es2015@^6.9.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939" + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.24.1" + babel-plugin-transform-es2015-classes "^6.24.1" + babel-plugin-transform-es2015-computed-properties "^6.24.1" + babel-plugin-transform-es2015-destructuring "^6.22.0" + babel-plugin-transform-es2015-duplicate-keys "^6.24.1" + babel-plugin-transform-es2015-for-of "^6.22.0" + babel-plugin-transform-es2015-function-name "^6.24.1" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-plugin-transform-es2015-modules-systemjs "^6.24.1" + babel-plugin-transform-es2015-modules-umd "^6.24.1" + babel-plugin-transform-es2015-object-super "^6.24.1" + babel-plugin-transform-es2015-parameters "^6.24.1" + babel-plugin-transform-es2015-shorthand-properties "^6.24.1" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.24.1" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.22.0" + babel-plugin-transform-es2015-unicode-regex "^6.24.1" + babel-plugin-transform-regenerator "^6.24.1" + +babel-preset-stage-1@^6.5.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz#7692cd7dcd6849907e6ae4a0a85589cfb9e2bfb0" + dependencies: + babel-plugin-transform-class-constructor-call "^6.24.1" + babel-plugin-transform-export-extensions "^6.22.0" + babel-preset-stage-2 "^6.24.1" + +babel-preset-stage-2@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz#d9e2960fb3d71187f0e64eec62bc07767219bdc1" + dependencies: + babel-plugin-syntax-dynamic-import "^6.18.0" + babel-plugin-transform-class-properties "^6.24.1" + babel-plugin-transform-decorators "^6.24.1" + babel-preset-stage-3 "^6.24.1" + +babel-preset-stage-3@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz#836ada0a9e7a7fa37cb138fb9326f87934a48395" + dependencies: + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-generator-functions "^6.24.1" + babel-plugin-transform-async-to-generator "^6.24.1" + babel-plugin-transform-exponentiation-operator "^6.24.1" + babel-plugin-transform-object-rest-spread "^6.22.0" + +babel-register@^6.26.0, babel-register@^6.9.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-7.0.0-beta.3.tgz#cd927ca70e0ae8ab05f4aab83778cfb3e6eb20b4" + dependencies: + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^2.0.0" + +babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@7.0.0-beta.40, babylon@^7.0.0-beta.40: + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.40.tgz#91fc8cd56d5eb98b28e6fde41045f2957779940a" + +babylon@^6.17.3, babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +base64-js@^1.0.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.3.tgz#fb13668233d9614cf5fb4bce95a9ba4096cdf801" + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + dependencies: + tweetnacl "^0.14.3" + +bfj-node4@^5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bfj-node4/-/bfj-node4-5.2.1.tgz#3a6aa2730cf6911ba2afb836c2f88f015d718f3f" + dependencies: + bluebird "^3.5.1" + check-types "^7.3.0" + tryer "^1.0.0" + +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + +binary-extensions@^1.0.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" + +binaryextensions@2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.1.1.tgz#3209a51ca4a4ad541a3b8d3d6a6d5b83a2485935" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +bluebird@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + +body-parser@1.18.2: + version "1.18.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" + dependencies: + 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" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +bootstrap-sass@^3.3: + version "3.3.7" + resolved "https://registry.yarnpkg.com/bootstrap-sass/-/bootstrap-sass-3.3.7.tgz#6596c7ab40f6637393323ab0bc80d064fc630498" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +braces@^2.3.0, braces@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.1.tgz#7086c913b4e5a08dbe37ac0ee6a2500c4ba691bb" + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + define-property "^1.0.0" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + kind-of "^6.0.2" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.1.1.tgz#38b7ab55edb806ff2dcda1a7f1620773a477c49f" + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.0.tgz#9988244874bf5ed4e28da95666dcd66ac8fc363a" + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.0.tgz#daa277717470922ed2fe18594118a175439721dd" + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + dependencies: + pako "~1.0.5" + +browserslist@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.1.1.tgz#d380fc048bc3a33e60fb87dc135110ebaaa6320a" + dependencies: + caniuse-lite "^1.0.30000809" + electron-to-chromium "^1.3.33" + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + +buffer@^4.3.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-modules@^1.0.0, builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + +cacache@^10.0.1: + version "10.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" + dependencies: + bluebird "^3.5.1" + chownr "^1.0.1" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.1" + mississippi "^2.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^5.2.4" + unique-filename "^1.1.0" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + +caniuse-lite@^1.0.30000809: + version "1.0.30000810" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000810.tgz#47585fffce0e9f3593a6feea4673b945424351d9" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.1.tgz#523fe2678aec7b04e8041909292fe8b17059b796" + dependencies: + ansi-styles "^3.2.0" + escape-string-regexp "^1.0.5" + supports-color "^5.2.0" + +chalk@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" + dependencies: + ansi-styles "~1.0.0" + has-color "~0.1.0" + strip-ansi "~0.1.0" + +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + +check-types@^7.3.0: + version "7.3.0" + resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.3.0.tgz#468f571a4435c24248f5fd0cb0e8d87c3c341e7d" + +chokidar@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.2.tgz#4dc65139eeb2714977735b6a35d06e97b494dfd7" + dependencies: + anymatch "^2.0.0" + async-each "^1.0.0" + braces "^2.3.0" + glob-parent "^3.1.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^2.1.1" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + upath "^1.0.0" + optionalDependencies: + fsevents "^1.0.0" + +chownr@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + +chrome-trace-event@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-0.1.2.tgz#90f36885d5345a50621332f0717b595883d5d982" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-webpack-plugin@^0.1.18: + version "0.1.18" + resolved "https://registry.yarnpkg.com/clean-webpack-plugin/-/clean-webpack-plugin-0.1.18.tgz#2e2173897c76646031bff047c14b9c22c80d8c4a" + dependencies: + rimraf "^2.6.1" + +cli-cursor@^1.0.1, cli-cursor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + dependencies: + restore-cursor "^1.0.1" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + dependencies: + restore-cursor "^2.0.0" + +cli-spinners@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" + +cli-table@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" + dependencies: + colors "1.0.3" + +cli-truncate@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + dependencies: + slice-ansi "0.0.4" + string-width "^1.0.1" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + +clone-stats@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + +clone@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f" + +clone@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb" + +cloneable-readable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.0.0.tgz#a6290d413f217a61232f95e458ff38418cfb0117" + dependencies: + inherits "^2.0.1" + process-nextick-args "^1.0.6" + through2 "^2.0.1" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +codecov@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.0.0.tgz#c273b8c4f12945723e8dc9d25803d89343e5f28e" + dependencies: + argv "0.0.2" + request "2.81.0" + urlgrey "0.4.4" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" + dependencies: + color-name "^1.1.1" + +color-name@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + +colors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + +colors@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" + dependencies: + delayed-stream "~1.0.0" + +commander@^2.13.0: + version "2.14.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa" + +commander@~2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + +component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +concat-stream@^1.4.7, concat-stream@^1.5.0, concat-stream@^1.6.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.1.tgz#261b8f518301f1d834e36342b9fea095d2620a26" + dependencies: + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + dependencies: + date-now "^0.1.4" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + +content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + +convert-source-map@^1.1.0, convert-source-map@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + +core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0: + version "2.5.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +create-ecdh@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.0.tgz#888c723596cdf7612f6498233eebd7a35301737d" + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd" + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + ripemd160 "^2.0.0" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.6" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.6.tgz#acb9e221a4e17bdb076e90657c42b93e3726cf06" + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@^5.0.1, cross-spawn@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" + +dargs@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/dargs/-/dargs-5.1.0.tgz#ec7ea50c78564cd36c9d5ec18f66329fade27829" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +date-fns@^1.27.2: + version "1.29.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + +dateformat@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062" + +debug@2.6.9, debug@^2.0.0, debug@^2.1.0, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + +debug@^3.0.1, debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + +decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + +decompress-response@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + dependencies: + mimic-response "^1.0.0" + +deep-extend@^0.4.0, deep-extend@~0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +define-properties@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + dependencies: + foreach "^2.0.5" + object-keys "^1.0.8" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +del@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +depd@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" + +depd@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + +detect-conflict@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/detect-conflict/-/detect-conflict-1.0.1.tgz#088657a66a961c05019db7c4230883b1c6b4176e" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + +diff@^2.1.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/diff/-/diff-2.2.3.tgz#60eafd0d28ee906e4e8ff0a52c1229521033bf99" + +diff@^3.3.0, diff@^3.3.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c" + +diffie-hellman@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e" + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^2.0.2, doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + dependencies: + esutils "^2.0.2" + +dom-walk@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + +duplexer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + +duplexify@^3.4.2, duplexify@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.3.tgz#8b5818800df92fd0125b27ab896491912858243e" + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +editions@^1.3.3: + version "1.3.4" + resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + +ejs@^2.3.1, ejs@^2.5.7: + version "2.5.7" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a" + +electron-to-chromium@^1.3.33: + version "1.3.34" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.34.tgz#d93498f40391bb0c16a603d8241b9951404157ed" + +elegant-spinner@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" + +elliptic@^6.0.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + +encodeurl@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + dependencies: + iconv-lite "~0.4.13" + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + dependencies: + once "^1.4.0" + +enhanced-resolve@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e" + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + object-assign "^4.0.1" + tapable "^0.2.7" + +enhanced-resolve@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.0.0.tgz#e34a6eaa790f62fccd71d93959f56b2b432db10a" + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + tapable "^1.0.0" + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + dependencies: + is-arrayish "^0.2.1" + +error@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/error/-/error-7.0.2.tgz#a5f75fff4d9926126ddac0ea5dc38e689153cb02" + dependencies: + string-template "~0.2.1" + xtend "~4.0.0" + +es-abstract@^1.7.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + +es-to-primitive@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" + dependencies: + is-callable "^1.1.1" + is-date-object "^1.0.1" + is-symbol "^1.0.1" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +eslint-import-resolver-node@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" + dependencies: + debug "^2.6.9" + resolve "^1.5.0" + +eslint-module-utils@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449" + dependencies: + debug "^2.6.8" + pkg-dir "^1.0.0" + +eslint-plugin-babel@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-babel/-/eslint-plugin-babel-4.1.2.tgz#79202a0e35757dd92780919b2336f1fa2fe53c1e" + +eslint-plugin-import@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.9.0.tgz#26002efbfca5989b7288ac047508bd24f217b169" + dependencies: + builtin-modules "^1.1.1" + contains-path "^0.1.0" + debug "^2.6.8" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.1" + eslint-module-utils "^2.1.1" + has "^1.0.1" + lodash "^4.17.4" + minimatch "^3.0.3" + read-pkg-up "^2.0.0" + +eslint-plugin-react@^7.7.0: + version "7.7.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.7.0.tgz#f606c719dbd8a1a2b3d25c16299813878cca0160" + dependencies: + doctrine "^2.0.2" + has "^1.0.1" + jsx-ast-utils "^2.0.1" + prop-types "^15.6.0" + +eslint-scope@^3.7.1, eslint-scope@~3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + +eslint@^4.18.1: + version "4.18.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.18.1.tgz#b9138440cb1e98b2f44a0d578c6ecf8eae6150b0" + dependencies: + ajv "^5.3.0" + babel-code-frame "^6.22.0" + chalk "^2.1.0" + concat-stream "^1.6.0" + cross-spawn "^5.1.0" + debug "^3.1.0" + doctrine "^2.1.0" + eslint-scope "^3.7.1" + eslint-visitor-keys "^1.0.0" + espree "^3.5.2" + esquery "^1.0.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.0.1" + ignore "^3.3.3" + imurmurhash "^0.1.4" + inquirer "^3.0.6" + is-resolvable "^1.0.0" + js-yaml "^3.9.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.4" + minimatch "^3.0.2" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + pluralize "^7.0.0" + progress "^2.0.0" + require-uncached "^1.0.3" + semver "^5.3.0" + strip-ansi "^4.0.0" + strip-json-comments "~2.0.1" + table "^4.0.1" + text-table "~0.2.0" + +espree@^3.5.2: + version "3.5.3" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.3.tgz#931e0af64e7fbbed26b050a29daad1fc64799fa6" + dependencies: + acorn "^5.4.0" + acorn-jsx "^3.0.0" + +esprima@^4.0.0, esprima@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" + +esquery@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + dependencies: + estraverse "^4.1.0" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +esutils@^2.0.0, esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + +events@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + dependencies: + homedir-polyfill "^1.0.1" + +express@^4.16.2: + version "4.16.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c" + dependencies: + accepts "~1.3.4" + 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.1" + encodeurl "~1.0.1" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.1.0" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.2" + path-to-regexp "0.1.7" + proxy-addr "~2.0.2" + qs "6.5.1" + range-parser "~1.2.0" + safe-buffer "5.1.1" + send "0.16.1" + serve-static "1.13.1" + setprototypeof "1.1.0" + statuses "~1.3.1" + type-is "~1.6.15" + utils-merge "1.0.1" + vary "~1.1.2" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.0, extend@~3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + +external-editor@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-1.1.1.tgz#12d7b0db850f7ff7e7081baf4005700060c4600b" + dependencies: + extend "^3.0.0" + spawn-sync "^1.0.15" + tmp "^0.0.29" + +external-editor@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.1.0.tgz#3d026a21b7f95b5726387d4200ac160d372c3b48" + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + +fast-deep-equal@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + +fbjs@^0.8.16: + version "0.8.16" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.9" + +figures@^1.3.5, figures@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +file-saver@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/file-saver/-/file-saver-1.3.3.tgz#cdd4c44d3aa264eac2f68ec165bc791c34af1232" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + +filesize@^3.5.11: + version "3.6.0" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.0.tgz#22d079615624bb6fd3c04026120628a41b3f4efa" + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +finalhandler@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" + dependencies: + debug "2.6.9" + encodeurl "~1.0.1" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.3.1" + unpipe "~1.0.0" + +find-cache-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^2.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + +first-chunk-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz#1bdecdb8e083c0664b91945581577a43a9f31d70" + dependencies: + readable-stream "^2.0.2" + +flat-cache@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" + dependencies: + circular-json "^0.3.1" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + +flow-parser@^0.*: + version "0.66.0" + resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.66.0.tgz#be583fefb01192aa5164415d31a6241b35718983" + +flush-write-stream@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.2.tgz#c81b90d8746766f1a609a46809946c45dd8ae417" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.4" + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8" + dependencies: + nan "^2.3.0" + node-pre-gyp "^0.6.39" + +fstream-ignore@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.0.2, function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +get-caller-file@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + dependencies: + assert-plus "^1.0.0" + +gh-got@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/gh-got/-/gh-got-6.0.0.tgz#d74353004c6ec466647520a10bd46f7299d268d0" + dependencies: + got "^7.0.0" + is-plain-obj "^1.1.0" + +github-username@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/github-username/-/github-username-4.1.0.tgz#cbe280041883206da4212ae9e4b5f169c30bf417" + dependencies: + gh-got "^6.0.0" + +glob-all@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-all/-/glob-all-3.1.0.tgz#8913ddfb5ee1ac7812656241b03d5217c64b02ab" + dependencies: + glob "^7.0.5" + yargs "~1.2.6" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob@^6.0.1: + version "6.0.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +global@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" + dependencies: + min-document "^2.19.0" + process "~0.5.1" + +globals@^11.0.1, globals@^11.1.0: + version "11.3.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.3.0.tgz#e04fdb7b9796d8adac9c8f64c14837b2313378b0" + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + +globby@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-4.1.0.tgz#080f54549ec1b82a6c60e631fc82e1211dbe95f8" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^6.0.1" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +got@^7.0.0, got@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" + dependencies: + decompress-response "^3.2.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-plain-obj "^1.1.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + p-cancelable "^0.3.0" + p-timeout "^1.1.1" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + url-parse-lax "^1.0.0" + url-to-options "^1.0.1" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +grouped-queue@^0.3.0, grouped-queue@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/grouped-queue/-/grouped-queue-0.3.3.tgz#c167d2a5319c5a0e0964ef6a25b7c2df8996c85c" + dependencies: + lodash "^4.17.2" + +gzip-size@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-4.1.0.tgz#8ae096257eabe7d69c45be2b67c448124ffb517c" + dependencies: + duplexer "^0.1.1" + pify "^3.0.0" + +har-schema@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" + +har-validator@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" + dependencies: + ajv "^4.9.1" + har-schema "^1.0.5" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-color@~0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + dependencies: + has-symbol-support-x "^1.4.1" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" + dependencies: + function-bind "^1.0.2" + +hash-base@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-2.0.2.tgz#66ea1d856db4e8a5470cadf6fce23ae5244ef2e1" + dependencies: + inherits "^2.0.1" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.0" + +hawk@3.1.3, hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +homedir-polyfill@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" + dependencies: + parse-passwd "^1.0.0" + +hosted-git-info@^2.1.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" + +http-errors@1.6.2, http-errors@~1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" + dependencies: + depd "1.1.1" + inherits "2.0.3" + setprototypeof "1.0.3" + statuses ">= 1.3.1 < 2" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + +iconv-lite@0.4.19, iconv-lite@^0.4.17, iconv-lite@~0.4.13: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + +ieee754@^1.1.4: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + +ignore@^3.3.3: + version "3.3.7" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + dependencies: + repeating "^2.0.0" + +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + +ini@^1.3.4, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + +inquirer@^1.0.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-1.2.3.tgz#4dec6f32f37ef7bb0b2ed3f1d1a5c3f545074918" + dependencies: + ansi-escapes "^1.1.0" + chalk "^1.0.0" + cli-cursor "^1.0.1" + cli-width "^2.0.0" + external-editor "^1.1.0" + figures "^1.3.5" + lodash "^4.3.0" + mute-stream "0.0.6" + pinkie-promise "^2.0.0" + run-async "^2.2.0" + rx "^4.1.0" + string-width "^1.0.1" + strip-ansi "^3.0.0" + through "^2.3.6" + +inquirer@^3.0.6, inquirer@^3.2.0, inquirer@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.4" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +interpret@^1.0.0, interpret@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" + +invariant@^2.2.0, invariant@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.3.tgz#1a827dfde7dcbd7c323f0ca826be8fa7c5e9d688" + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +ipaddr.js@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.6.0.tgz#e3fa357b773da619f26e95f049d055c72796f86b" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-callable@^1.1.1, is-callable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + dependencies: + is-extglob "^2.1.1" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + +is-odd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" + dependencies: + is-number "^4.0.0" + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + +is-path-in-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + dependencies: + path-is-inside "^1.0.1" + +is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + dependencies: + isobject "^3.0.1" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" + +is-resolvable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + +is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + +is-scoped@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-scoped/-/is-scoped-1.0.0.tgz#449ca98299e713038256289ecb2b540dc437cb30" + dependencies: + scoped-regex "^1.0.0" + +is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-symbol@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +istextorbinary@^2.1.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-2.2.1.tgz#a5231a08ef6dd22b268d0895084cf8d58b5bec53" + dependencies: + binaryextensions "2" + editions "^1.3.3" + textextensions "2" + +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + +jquery@^1.12.4: + version "1.12.4" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-1.12.4.tgz#01e1dfba290fe73deba77ceeacb0f9ba2fec9e0c" + +js-tokens@^3.0.0, js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +js-yaml@^3.9.1: + version "3.10.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +jscodeshift@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.4.1.tgz#da91a1c2eccfa03a3387a21d39948e251ced444a" + dependencies: + async "^1.5.0" + babel-plugin-transform-flow-strip-types "^6.8.0" + babel-preset-es2015 "^6.9.0" + babel-preset-stage-1 "^6.5.0" + babel-register "^6.9.0" + babylon "^6.17.3" + colors "^1.1.2" + flow-parser "^0.*" + lodash "^4.13.1" + micromatch "^2.3.7" + node-dir "0.1.8" + nomnom "^1.8.1" + recast "^0.12.5" + temp "^0.8.1" + write-file-atomic "^1.2.0" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json5@^0.5.0, json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +jsx-ast-utils@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f" + dependencies: + array-includes "^3.0.3" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + +lazy-cache@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264" + dependencies: + set-getter "^0.1.0" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +listr-silent-renderer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" + +listr-update-renderer@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz#ca80e1779b4e70266807e8eed1ad6abe398550f9" + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^1.0.2" + strip-ansi "^3.0.1" + +listr-verbose-renderer@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35" + dependencies: + chalk "^1.1.3" + cli-cursor "^1.0.2" + date-fns "^1.27.2" + figures "^1.7.0" + +listr@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/listr/-/listr-0.12.0.tgz#6bce2c0f5603fa49580ea17cd6a00cc0e5fa451a" + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + figures "^1.7.0" + indent-string "^2.1.0" + is-promise "^2.1.0" + is-stream "^1.1.0" + listr-silent-renderer "^1.1.1" + listr-update-renderer "^0.2.0" + listr-verbose-renderer "^0.4.0" + log-symbols "^1.0.2" + log-update "^1.0.2" + ora "^0.2.3" + p-map "^1.1.1" + rxjs "^5.0.0-beta.11" + stream-to-observable "^0.1.0" + strip-ansi "^3.0.1" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +loader-runner@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" + +loader-utils@^1.0.2, loader-utils@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +lodash-webpack-plugin@^0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/lodash-webpack-plugin/-/lodash-webpack-plugin-0.11.4.tgz#6c3ecba3d4b8d24b53940b63542715c5ed3c4ac5" + dependencies: + lodash "^4.17.4" + +lodash@^4.11.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0: + version "4.17.5" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" + +log-symbols@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.1.0.tgz#f35fa60e278832b538dc4dddcbb478a45d3e3be6" + dependencies: + chalk "^2.0.1" + +log-symbols@^1.0.1, log-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + dependencies: + chalk "^1.0.0" + +log-symbols@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + dependencies: + chalk "^2.0.1" + +log-update@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1" + dependencies: + ansi-escapes "^1.0.0" + cli-cursor "^1.0.2" + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +lowercase-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + +lru-cache@^4.0.1, lru-cache@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +make-dir@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.2.0.tgz#6d6a49eead4aae296c53bbf3a1a008bd6c89469b" + dependencies: + pify "^3.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + dependencies: + object-visit "^1.0.0" + +md5.js@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + +mem-fs-editor@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/mem-fs-editor/-/mem-fs-editor-3.0.2.tgz#dd0a6eaf2bb8a6b37740067aa549eb530105af9f" + dependencies: + commondir "^1.0.1" + deep-extend "^0.4.0" + ejs "^2.3.1" + glob "^7.0.3" + globby "^6.1.0" + mkdirp "^0.5.0" + multimatch "^2.0.0" + rimraf "^2.2.8" + through2 "^2.0.0" + vinyl "^2.0.1" + +mem-fs@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/mem-fs/-/mem-fs-1.1.3.tgz#b8ae8d2e3fcb6f5d3f9165c12d4551a065d989cc" + dependencies: + through2 "^2.0.0" + vinyl "^1.1.0" + vinyl-file "^2.0.0" + +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + dependencies: + mimic-fn "^1.0.0" + +memory-fs@^0.4.0, memory-fs@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + +micromatch@^2.3.11, micromatch@^2.3.7: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +micromatch@^3.1.4, micromatch@^3.1.8: + version "3.1.9" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.9.tgz#15dc93175ae39e52e93087847096effc73efcf89" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@~1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" + +mime-types@^2.1.12, mime-types@~2.1.18, mime-types@~2.1.7: + version "2.1.18" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" + dependencies: + mime-db "~1.33.0" + +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + +mimic-response@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e" + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + dependencies: + dom-walk "^0.1.0" + +minimalistic-assert@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3" + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.1.0.tgz#99df657a52574c21c9057497df742790b2b4c0de" + +minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +mississippi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f" + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^2.0.1" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +multimatch@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +mute-stream@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.6.tgz#48962b19e169fd1dfc240b3f1e7317627bbc47db" + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + +nan@^2.3.0: + version "2.9.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.9.2.tgz#f564d75f5f8f36a6d9456cca7a6c4fe488ab7866" + +nanomatch@^1.2.9: + version "1.2.9" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-odd "^2.0.0" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + +neo-async@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.0.tgz#76b1c823130cca26acfbaccc8fbaf0a2fa33b18f" + +node-dir@0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.8.tgz#55fb8deb699070707fb67f91a460f0448294c77d" + +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-libs-browser@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^1.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.0" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.10.3" + vm-browserify "0.0.4" + +node-pre-gyp@^0.6.39: + version "0.6.39" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649" + dependencies: + detect-libc "^1.0.2" + hawk "3.1.3" + mkdirp "^0.5.1" + nopt "^4.0.1" + npmlog "^4.0.2" + rc "^1.1.7" + request "2.81.0" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^2.2.1" + tar-pack "^3.4.0" + +nomnom@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" + dependencies: + chalk "~0.4.0" + underscore "~1.6.0" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.3.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.1, normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + dependencies: + path-key "^2.0.0" + +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +oauth-sign@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-keys@^1.0.8: + version "1.0.11" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + dependencies: + isobject "^3.0.0" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + dependencies: + isobject "^3.0.1" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" + +opener@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8" + +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +ora@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" + dependencies: + chalk "^1.1.1" + cli-cursor "^1.0.2" + cli-spinners "^0.1.2" + object-assign "^4.0.1" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + +os-shim@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-cancelable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" + +p-each-series@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" + dependencies: + p-reduce "^1.0.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + +p-lazy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-lazy/-/p-lazy-1.0.0.tgz#ec53c802f2ee3ac28f166cc82d0b2b02de27a835" + +p-limit@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" + dependencies: + p-try "^1.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + +p-map@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + +p-reduce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" + +p-timeout@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" + dependencies: + p-finally "^1.0.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + +pako@~1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" + +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" + +parse-asn1@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.0.tgz#37c4f9b7ed3ab65c74817b5f2480937fbf97c712" + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + +parseurl@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + +path-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-is-inside@^1.0.1, path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + dependencies: + pify "^2.0.0" + +pbkdf2@^3.0.3: + version "3.0.14" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.14.tgz#a35e13c64799b06ce15320f459c230e68e73bade" + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + +pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + dependencies: + find-up "^1.0.0" + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + dependencies: + find-up "^2.1.0" + +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +prettier@^1.5.3: + version "1.11.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.1.tgz#61e43fc4cd44e68f2b0dfc2c38cd4bb0fccdcc75" + +pretty-bytes@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9" + +private@^0.1.6, private@^0.1.7, private@~0.1.5: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + +process-nextick-args@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + +process@~0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + +progress@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + dependencies: + asap "~2.0.3" + +prop-types@^15.6.0, prop-types@^15.6.1: + version "15.6.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca" + dependencies: + fbjs "^0.8.16" + loose-envify "^1.3.1" + object-assign "^4.1.1" + +proxy-addr@~2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341" + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.6.0" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +public-encrypt@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6" + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + +pump@^2.0.0, pump@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.4.0.tgz#80b7c5df7e24153d03f0e7ac8a05a5d068bd07fb" + dependencies: + duplexify "^3.5.3" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + +punycode@^1.2.4, punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +qs@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + +qs@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + +randomatic@^1.1.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + +raw-body@2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" + dependencies: + bytes "3.0.0" + http-errors "1.6.2" + iconv-lite "0.4.19" + unpipe "1.0.0" + +rc@^1.1.7: + version "1.2.5" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.5.tgz#275cd687f6e3b36cc756baa26dfee80a790301fd" + dependencies: + deep-extend "~0.4.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-dom@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.2.0.tgz#69003178601c0ca19b709b33a83369fe6124c044" + dependencies: + fbjs "^0.8.16" + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.0" + +react@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.2.0.tgz#a31bd2dab89bff65d42134fa187f24d054c273ba" + dependencies: + fbjs "^0.8.16" + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.0" + +read-chunk@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-2.1.0.tgz#6a04c0928005ed9d42e1a6ac5600e19cbc7ff655" + dependencies: + pify "^3.0.0" + safe-buffer "^5.1.1" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.4.tgz#c946c3f47fa7d8eabc0b6150f4a12f69a4574071" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.0.3" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" + dependencies: + graceful-fs "^4.1.2" + minimatch "^3.0.2" + readable-stream "^2.0.2" + set-immediate-shim "^1.0.1" + +recast@^0.12.5: + version "0.12.9" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.12.9.tgz#e8e52bdb9691af462ccbd7c15d5a5113647a15f1" + dependencies: + ast-types "0.10.1" + core-js "^2.4.1" + esprima "~4.0.0" + private "~0.1.5" + source-map "~0.6.1" + +recast@^0.13.0: + version "0.13.2" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.13.2.tgz#919e7e856d5154f13284142ed1797753c6756137" + dependencies: + ast-types "0.10.2" + esprima "~4.0.0" + private "~0.1.5" + source-map "~0.6.1" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + dependencies: + resolve "^1.1.6" + +regenerate-unicode-properties@^5.1.1: + version "5.1.3" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-5.1.3.tgz#54f5891543468f36f2274b67c6bc4c033c27b308" + dependencies: + regenerate "^1.3.3" + +regenerate@^1.2.1, regenerate@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regenerator-transform@^0.12.3: + version "0.12.3" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.12.3.tgz#459adfb64f6a27164ab991b7873f45ab969eca8b" + dependencies: + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + dependencies: + is-equal-shallow "^0.1.3" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regexpu-core@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.1.3.tgz#fb81616dbbc2a917a7419b33f8379144f51eb8d0" + dependencies: + regenerate "^1.3.3" + regenerate-unicode-properties "^5.1.1" + regjsgen "^0.3.0" + regjsparser "^0.2.1" + unicode-match-property-ecmascript "^1.0.3" + unicode-match-property-value-ecmascript "^1.0.1" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsgen@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.3.0.tgz#0ee4a3e9276430cda25f1e789ea6c15b87b0cb43" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + +regjsparser@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.2.1.tgz#c3787553faf04e775c302102ef346d995000ec1c" + dependencies: + jsesc "~0.5.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.2, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +replace-ext@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" + +replace-ext@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + +request@2.81.0: + version "2.81.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" + dependencies: + 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" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +require-package-name@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9" + +require-uncached@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + dependencies: + resolve-from "^3.0.0" + +resolve-dir@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + +resolve@^1.1.6, resolve@^1.3.2, resolve@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" + dependencies: + path-parse "^1.0.5" + +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + +rimraf@2, rimraf@^2.2.0, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + dependencies: + glob "^7.0.5" + +rimraf@~2.2.6: + version "2.2.8" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.1.tgz#0f4584295c53a3628af7e6d79aca21ce57d1c6e7" + dependencies: + hash-base "^2.0.0" + inherits "^2.0.1" + +run-async@^2.0.0, run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + dependencies: + is-promise "^2.1.0" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + dependencies: + aproba "^1.1.1" + +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + +rx@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" + +rxjs@^5.0.0-beta.11: + version "5.5.6" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.6.tgz#e31fb96d6fd2ff1fd84bcea8ae9c02d007179c02" + dependencies: + symbol-observable "1.0.1" + +safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + dependencies: + ret "~0.1.10" + +schema-utils@^0.4.2: + version "0.4.5" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.5.tgz#21836f0608aac17b78f9e3e24daff14a5ca13a3e" + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + +scoped-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/scoped-regex/-/scoped-regex-1.0.0.tgz#a346bb1acd4207ae70bd7c0c7ca9e566b6baddb8" + +"semver@2 || 3 || 4 || 5", semver@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + +send@0.16.1: + version "0.16.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3" + dependencies: + debug "2.6.9" + depd "~1.1.1" + destroy "~1.0.4" + encodeurl "~1.0.1" + 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.3.1" + +serialize-javascript@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.4.0.tgz#7c958514db6ac2443a8abc062dc9f7886a7f6005" + +serve-static@1.13.1: + version "1.13.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719" + dependencies: + encodeurl "~1.0.1" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.1" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-getter@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.0.tgz#d769c182c9d5a51f409145f2fba82e5e86e80376" + dependencies: + to-object-path "^0.3.0" + +set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4, setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + +setprototypeof@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.10" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.10.tgz#b1fde5cd7d11a5626638a07c604ab909cfa31f9b" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +shelljs@^0.7.0: + version "0.7.8" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + +slice-ansi@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + dependencies: + is-fullwidth-code-point "^2.0.0" + +slide@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.1.tgz#e12b5487faded3e3dea0ac91e9400bf75b401370" + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^2.0.0" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +source-list-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" + +source-map-resolve@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.1.tgz#7ad0f593f2281598e854df80f19aae4b92d7a11a" + dependencies: + atob "^2.0.0" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + dependencies: + source-map "^0.5.6" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + +source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + +spawn-sync@^1.0.15: + version "1.0.15" + resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476" + dependencies: + concat-stream "^1.4.7" + os-shim "^0.1.2" + +spdx-correct@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82" + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9" + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +sshpk@^1.7.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +ssri@^5.2.4: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.2.4.tgz#9985e14041e65fc397af96542be35724ac11da52" + dependencies: + safe-buffer "^5.1.1" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.3.1 < 2": + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + +statuses@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + +stream-browserify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd" + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.0" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.0.tgz#fd86546dac9b1c91aff8fc5d287b98fafb41bc10" + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.3" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + +stream-to-observable@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.1.0.tgz#45bf1d9f2d7dc09bed81f1c307c430e68b84cffe" + +string-template@~0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@^1.0.0, string_decoder@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" + dependencies: + safe-buffer "~5.1.0" + +stringstream@~0.0.4: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" + +strip-bom-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz#f87db5ef2613f6968aa545abfe1ec728b6a829ca" + dependencies: + first-chunk-stream "^2.0.0" + strip-bom "^2.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" + dependencies: + has-flag "^2.0.0" + +supports-color@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.2.0.tgz#b0d5333b1184dd3666cbe5aa0b45c5ac7ac17a4a" + dependencies: + has-flag "^3.0.0" + +symbol-observable@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" + +table@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc" + dependencies: + ajv "^6.0.1" + ajv-keywords "^3.0.0" + chalk "^2.1.0" + lodash "^4.17.4" + slice-ansi "1.0.0" + string-width "^2.1.1" + +tapable@^0.2.7: + version "0.2.8" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22" + +tapable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2" + +tar-pack@^3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f" + dependencies: + debug "^2.2.0" + fstream "^1.0.10" + fstream-ignore "^1.0.5" + once "^1.3.3" + readable-stream "^2.1.4" + rimraf "^2.5.1" + tar "^2.2.1" + uid-number "^0.0.6" + +tar@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +temp@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" + dependencies: + os-tmpdir "^1.0.0" + rimraf "~2.2.6" + +text-table@^0.2.0, text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + +textextensions@2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.2.0.tgz#38ac676151285b658654581987a0ce1a4490d286" + +through2@^2.0.0, through2@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + +timers-browserify@^2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.6.tgz#241e76927d9ca05f4d959819022f5b3664b64bae" + dependencies: + setimmediate "^1.0.4" + +tmp@^0.0.29: + version "0.0.29" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.29.tgz#f25125ff0dd9da3ccb0c2dd371ee1288bb9128c0" + dependencies: + os-tmpdir "~1.0.1" + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + dependencies: + os-tmpdir "~1.0.2" + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +tough-cookie@~2.3.0: + version "2.3.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" + dependencies: + punycode "^1.4.1" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + +tryer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.0.tgz#027b69fa823225e551cace3ef03b11f6ab37c1d7" + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +type-is@~1.6.15: + version "1.6.16" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" + dependencies: + media-typer "0.3.0" + mime-types "~2.1.18" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +ua-parser-js@^0.7.9: + version "0.7.17" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" + +uglify-es@^3.3.4: + version "3.3.9" + resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" + dependencies: + commander "~2.13.0" + source-map "~0.6.1" + +uglifyjs-webpack-plugin@^1.1.1, uglifyjs-webpack-plugin@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.2.tgz#e7516d4367afdb715c3847841eb46f94c45ca2b9" + dependencies: + cacache "^10.0.1" + find-cache-dir "^1.0.0" + schema-utils "^0.4.2" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + uglify-es "^3.3.4" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + +uid-number@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + +underscore@~1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" + +unicode-canonical-property-names-ecmascript@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.3.tgz#f6119f417467593c0086357c85546b6ad5abc583" + +unicode-match-property-ecmascript@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.3.tgz#db9b1cb4ffc67e0c5583780b1b59370e4cbe97b9" + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.2" + unicode-property-aliases-ecmascript "^1.0.3" + +unicode-match-property-value-ecmascript@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.1.tgz#fea059120a016f403afd3bf586162b4db03e0604" + +unicode-property-aliases-ecmascript@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.3.tgz#ac3522583b9e630580f916635333e00c5ead690d" + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +unique-filename@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3" + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.0.tgz#db6676e7c7cc0629878ff196097c78855ae9f4ab" + dependencies: + imurmurhash "^0.1.4" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +untildify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" + dependencies: + os-homedir "^1.0.0" + +untildify@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.2.tgz#7f1f302055b3fea0f3e81dc78eb36766cb65e3f1" + +upath@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.0.4.tgz#ee2321ba0a786c50973db043a50b7bcba822361d" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + dependencies: + prepend-http "^1.0.1" + +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +urlgrey@0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/urlgrey/-/urlgrey-0.4.4.tgz#892fe95960805e85519f1cd4389f2cb4cbb7652f" + +use@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/use/-/use-2.0.2.tgz#ae28a0d72f93bf22422a18a2e379993112dec8e8" + dependencies: + define-property "^0.2.5" + isobject "^3.0.0" + lazy-cache "^2.0.2" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +util@0.10.3, util@^0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + dependencies: + inherits "2.0.1" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + +uuid@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" + +v8-compile-cache@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-1.1.2.tgz#8d32e4f16974654657e676e0e467a348e89b0dc4" + +validate-npm-package-license@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz#81643bcbef1bdfecd4623793dc4648948ba98338" + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vinyl-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/vinyl-file/-/vinyl-file-2.0.0.tgz#a7ebf5ffbefda1b7d18d140fcb07b223efb6751a" + dependencies: + graceful-fs "^4.1.2" + pify "^2.3.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + strip-bom-stream "^2.0.0" + vinyl "^1.1.0" + +vinyl@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.1.0.tgz#021f9c2cf951d6b939943c89eb5ee5add4fd924c" + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +vm-browserify@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + dependencies: + indexof "0.0.1" + +watchpack@^1.4.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.5.0.tgz#231e783af830a22f8966f65c4c4bacc814072eed" + dependencies: + chokidar "^2.0.2" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + +webpack-addons@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/webpack-addons/-/webpack-addons-1.1.5.tgz#2b178dfe873fb6e75e40a819fa5c26e4a9bc837a" + dependencies: + jscodeshift "^0.4.0" + +webpack-bundle-analyzer@^2.11.1: + version "2.11.1" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.11.1.tgz#b9fbfb6a32c0a8c1c3237223e90890796b950ab9" + dependencies: + acorn "^5.3.0" + bfj-node4 "^5.2.0" + chalk "^2.3.0" + commander "^2.13.0" + ejs "^2.5.7" + express "^4.16.2" + filesize "^3.5.11" + gzip-size "^4.1.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + opener "^1.4.3" + ws "^4.0.0" + +webpack-cli@^2.0.9: + version "2.0.9" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-2.0.9.tgz#0310fa04f4cad69714560cc0e4da5c7682eb4d9b" + dependencies: + chalk "^2.0.1" + codecov "^3.0.0" + cross-spawn "^5.1.0" + diff "^3.3.0" + enhanced-resolve "^3.4.1" + glob-all "^3.1.0" + global "^4.3.2" + global-modules "^1.0.0" + got "^7.1.0" + inquirer "^3.2.0" + interpret "^1.0.4" + jscodeshift "^0.4.0" + listr "^0.12.0" + loader-utils "^1.1.0" + lodash "^4.17.4" + log-symbols "2.1.0" + mkdirp "^0.5.1" + p-each-series "^1.0.0" + p-lazy "^1.0.0" + prettier "^1.5.3" + recast "^0.13.0" + resolve-cwd "^2.0.0" + supports-color "^4.4.0" + uglifyjs-webpack-plugin "^1.2.2" + v8-compile-cache "^1.1.0" + webpack-addons "^1.1.5" + webpack-fork-yeoman-generator "^1.1.1" + yargs "9.0.1" + yeoman-environment "^2.0.0" + +webpack-fork-yeoman-generator@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/webpack-fork-yeoman-generator/-/webpack-fork-yeoman-generator-1.1.1.tgz#c92b454aba7df9ea392669188aa0330964acf76f" + dependencies: + async "^2.0.0" + chalk "^1.0.0" + cli-table "^0.3.1" + cross-spawn "^5.0.1" + dargs "^5.1.0" + dateformat "^2.0.0" + debug "^2.1.0" + detect-conflict "^1.0.0" + error "^7.0.2" + find-up "^2.1.0" + github-username "^4.0.0" + istextorbinary "^2.1.0" + lodash "^4.11.1" + mem-fs-editor "^3.0.0" + minimist "^1.2.0" + mkdirp "^0.5.0" + pretty-bytes "^4.0.2" + read-chunk "^2.0.0" + read-pkg-up "^2.0.0" + rimraf "^2.2.0" + run-async "^2.0.0" + shelljs "^0.7.0" + text-table "^0.2.0" + through2 "^2.0.0" + yeoman-environment "^1.1.0" + +webpack-merge@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.1.2.tgz#5d372dddd3e1e5f8874f5bf5a8e929db09feb216" + dependencies: + lodash "^4.17.5" + +webpack-sources@^1.0.1, webpack-sources@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.0.1.tgz#768d708beeca4c5f77f6c2d38a240fb6ff50ba5d" + dependencies: + acorn "^5.0.0" + acorn-dynamic-import "^3.0.0" + ajv "^6.1.0" + ajv-keywords "^3.1.0" + chrome-trace-event "^0.1.1" + enhanced-resolve "^4.0.0" + eslint-scope "^3.7.1" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + micromatch "^3.1.8" + mkdirp "~0.5.0" + neo-async "^2.5.0" + node-libs-browser "^2.0.0" + schema-utils "^0.4.2" + tapable "^1.0.0" + uglifyjs-webpack-plugin "^1.1.1" + watchpack "^1.4.0" + webpack-sources "^1.0.1" + +whatwg-fetch@>=0.10.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + +which@^1.2.14, which@^1.2.9: + version "1.3.0" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" + dependencies: + string-width "^1.0.2" + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +worker-farm@^1.5.2: + version "1.5.4" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.5.4.tgz#4debbe46b40edefcc717ebde74a90b1ae1e909a1" + dependencies: + errno "~0.1.7" + xtend "~4.0.1" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write-file-atomic@^1.2.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + slide "^1.1.5" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + +ws@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-4.1.0.tgz#a979b5d7d4da68bf54efe0408967c324869a7289" + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + +xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +yargs-parser@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" + dependencies: + camelcase "^4.1.0" + +yargs@9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c" + dependencies: + camelcase "^4.1.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + read-pkg-up "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^7.0.0" + +yargs@~1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-1.2.6.tgz#9c7b4a82fd5d595b2bf17ab6dcc43135432fe34b" + dependencies: + minimist "^0.1.0" + +yeoman-environment@^1.1.0: + version "1.6.6" + resolved "https://registry.yarnpkg.com/yeoman-environment/-/yeoman-environment-1.6.6.tgz#cd85fa67d156060e440d7807d7ef7cf0d2d1d671" + dependencies: + chalk "^1.0.0" + debug "^2.0.0" + diff "^2.1.2" + escape-string-regexp "^1.0.2" + globby "^4.0.0" + grouped-queue "^0.3.0" + inquirer "^1.0.2" + lodash "^4.11.1" + log-symbols "^1.0.1" + mem-fs "^1.1.0" + text-table "^0.2.0" + untildify "^2.0.0" + +yeoman-environment@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/yeoman-environment/-/yeoman-environment-2.0.5.tgz#84f22bafa84088971fe99ea85f654a3a3dd2b693" + dependencies: + chalk "^2.1.0" + debug "^3.1.0" + diff "^3.3.1" + escape-string-regexp "^1.0.2" + globby "^6.1.0" + grouped-queue "^0.3.3" + inquirer "^3.3.0" + is-scoped "^1.0.0" + lodash "^4.17.4" + log-symbols "^2.1.0" + mem-fs "^1.1.0" + text-table "^0.2.0" + untildify "^3.0.2" diff --git a/votrfront/serve.py b/votrfront/serve.py index cc430bc..75ad531 100644 --- a/votrfront/serve.py +++ b/votrfront/serve.py @@ -1,7 +1,6 @@ import os from werkzeug.serving import run_simple -from .watchstatic import watch_in_background def serve(app, *args): @@ -17,8 +16,6 @@ def serve(app, *args): os.makedirs(app.var_path('oldlogs'), exist_ok=True) os.makedirs(app.var_path('sessions'), exist_ok=True) - if os.getenv('WERKZEUG_RUN_MAIN'): - watch_in_background() app.wrap_static() run_simple('127.0.0.1', int(os.getenv('PORT') or 5000), app, diff --git a/votrfront/watchstatic.py b/votrfront/watchstatic.py deleted file mode 100644 index 9cc8e02..0000000 --- a/votrfront/watchstatic.py +++ /dev/null @@ -1,67 +0,0 @@ - -import os -import subprocess -import sys -import threading -import time - - -votrfront_path = os.path.dirname(__file__) or '.' -watch_paths = ['buildstatic.sh', 'js', 'css'] -watch_extensions = ['.sh', '.js', '.scss'] - - -def build(): - command = ['./buildstatic.sh'] - if hasattr(sys, 'real_prefix'): - command.append('--env=' + sys.prefix) - returncode = subprocess.call(command, cwd=votrfront_path) - print(' * buildstatic.sh failed' if returncode else - ' * buildstatic.sh ended successfully', file=sys.stderr) - - -def walk(root): - if os.path.isfile(root): - yield root - if os.path.isdir(root): - for dirpath, dirnames, filenames in os.walk(root): - for filename in filenames: - yield os.path.join(dirpath, filename) - - -def watch(interval=1): - last_build = time.time() - build() - - while True: - modified_files = [] - - for root in watch_paths: - for filename in walk(os.path.join(votrfront_path, root)): - if os.path.splitext(filename)[1] not in watch_extensions: - continue - try: - mtime = os.stat(filename).st_mtime - if mtime > last_build: - modified_files.append(filename) - except OSError: - continue - - if modified_files: - print(' * Detected change in {}, rebuilding static'.format( - repr(modified_files)[1:-1]), file=sys.stderr) - last_build = time.time() - build() - - time.sleep(interval) - - -def watch_in_background(): - t = threading.Thread(target=watch) - t.daemon = True - t.start() - return t - - -if __name__ == '__main__': - watch() diff --git a/votrfront/webpack.config.js b/votrfront/webpack.config.js deleted file mode 100644 index f610fe0..0000000 --- a/votrfront/webpack.config.js +++ /dev/null @@ -1,79 +0,0 @@ - -var webpack = require("webpack"); -var ConcatSource = require("webpack/lib/ConcatSource"); - - -function VotrDevelPlugin(moduleVariablePrefix, outputPath) { - this.moduleVariablePrefix = moduleVariablePrefix; - this.outputPath = outputPath; -} - -VotrDevelPlugin.prototype.apply = function (compiler) { - var self = this; - compiler.plugin('compilation', function (compilation) { - compilation.moduleTemplate.plugin('package', function (moduleSource, module) { - // Ugly hack to remove the newlines added by FunctionModuleTemplatePlugin. - if (moduleSource instanceof ConcatSource && moduleSource.children[0].constructor === String) { - moduleSource.children[0] = moduleSource.children[0].replace(/\n*$/, ''); - } - - // Uglier hack to move the whole source code to a separate file. - var id = self.moduleVariablePrefix + module.id; - var req = module.readableIdentifier(this.requestShortener); - var devFilename = self.outputPath + req.replace(/\.\w+$/, '').replace(/^\.\//, '').replace(/\W/g, '_') + '.js'; - - compilation.assets[devFilename] = new ConcatSource(id, ' = ', moduleSource); - return id; - }); - }); -}; - - -function makeConfig() { - return { - context: __dirname + '/js', - entry: './main', - output: { - path: __dirname + '/static', - sourceMapFilename: '[file].' + Date.now() + '.map', // it seems Chrome caches source maps even if "Disable cache" is enabled - }, - plugins: [], - module: { - loaders: [ - { - test: /\.js$/, - exclude: /node_modules/, - loader: 'babel', - query: { - cacheDirectory: __dirname + '/static/cache', - loose: ['es6.destructuring', 'es6.properties.computed', 'es6.spread'], - }, - }, - ], - }, - records: __dirname + '/static/records', - }; -}; - - -var prodConfig = makeConfig(); -prodConfig.output.filename = 'votr.min.js'; -prodConfig.plugins.push(new webpack.optimize.UglifyJsPlugin()); -prodConfig.plugins.push(new webpack.optimize.OccurenceOrderPlugin()); -prodConfig.devtool = 'source-map'; - - -var devConfig = makeConfig(); -devConfig.output.filename = 'votr.dev.js'; -devConfig.plugins.push(new VotrDevelPlugin('_votr_module_', 'dev/')); -devConfig.module.loaders[0].query.retainLines = true; - - -var prologueConfig = makeConfig(); -prologueConfig.entry = './prologue'; -prologueConfig.output.filename = 'prologue.js'; -prologueConfig.plugins.push(new webpack.optimize.UglifyJsPlugin()); -prologueConfig.plugins.push(new webpack.optimize.OccurenceOrderPlugin()); - - -module.exports = [prodConfig, devConfig, prologueConfig];