From 7f8bfc8faae604ee733354af80fc61234d1d6ff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sat, 9 Feb 2019 19:42:36 +0400 Subject: [PATCH] :tada: First commit, from couchbase generator, basic changes not tested / updated yet --- .gitignore | 4 + .travis.yml | 12 + LICENSE | 21 + README.md | 126 + cookiecutter.json | 45 + screenshot.png | Bin 0 -> 86808 bytes scripts/discard-dev-files.sh | 13 + scripts/generate_cookiecutter_config.py | 20 + test.sh | 14 + testing-config.yml | 2 + {{cookiecutter.project_slug}}/.env | 16 + {{cookiecutter.project_slug}}/.gitignore | 2 + {{cookiecutter.project_slug}}/.gitlab-ci.yml | 74 + {{cookiecutter.project_slug}}/README.md | 755 + .../backend/.gitignore | 1 + .../backend/app/Pipfile | 33 + .../backend/app/Pipfile.lock | 904 + .../backend/app/alembic/README | 1 + .../backend/app/alembic/env.py | 76 + .../backend/app/alembic/script.py.mako | 24 + .../backend/app/alembic/versions/.keep | 0 .../backend/app/app/__init__.py | 0 .../backend/app/app/api/__init__.py | 0 .../backend/app/app/api/api_v1/__init__.py | 0 .../backend/app/app/api/api_v1/api.py | 12 + .../app/app/api/api_v1/endpoints/__init__.py | 0 .../app/app/api/api_v1/endpoints/role.py | 25 + .../app/app/api/api_v1/endpoints/token.py | 96 + .../app/app/api/api_v1/endpoints/user.py | 205 + .../app/app/api/api_v1/endpoints/utils.py | 36 + .../backend/app/app/backend_pre_start.py | 32 + .../backend/app/app/celeryworker_pre_start.py | 32 + .../backend/app/app/core/__init__.py | 0 .../backend/app/app/core/celery_app.py | 5 + .../backend/app/app/core/config.py | 78 + .../backend/app/app/core/jwt.py | 44 + .../backend/app/app/core/security.py | 11 + .../backend/app/app/crud/__init__.py | 0 .../backend/app/app/crud/user.py | 91 + .../backend/app/app/crud/utils.py | 214 + .../backend/app/app/db/__init__.py | 0 .../backend/app/app/db/base.py | 5 + .../backend/app/app/db/base_class.py | 11 + .../backend/app/app/db/external_session.py | 8 + .../app/app/db/full_text_search_utils.py | 106 + .../backend/app/app/db/init_db.py | 29 + .../backend/app/app/db_models/__init__.py | 0 .../app/app/db_models/base_relations.py | 11 + .../backend/app/app/db_models/role.py | 19 + .../backend/app/app/db_models/user.py | 29 + .../email-templates/build/new_account.html | 26 + .../email-templates/build/reset_password.html | 26 + .../app/email-templates/build/test_email.html | 25 + .../app/email-templates/src/new_account.mjml | 15 + .../email-templates/src/reset_password.mjml | 19 + .../app/email-templates/src/test_email.mjml | 11 + .../backend/app/app/main.py | 26 + .../backend/app/app/models/__init__.py | 0 .../backend/app/app/models/config.py | 1 + .../backend/app/app/models/msg.py | 5 + .../backend/app/app/models/role.py | 14 + .../backend/app/app/models/token.py | 10 + .../backend/app/app/models/user.py | 48 + .../app/search_index_definitions/users.json | 15 + .../search_index_definitions/users_01.json | 157 + .../backend/app/app/tests/.gitignore | 1 + .../backend/app/app/tests/__init__.py | 0 .../backend/app/app/tests/api/__init__.py | 0 .../app/app/tests/api/api_v1/__init__.py | 0 .../app/app/tests/api/api_v1/test_celery.py | 16 + .../app/app/tests/api/api_v1/test_token.py | 30 + .../app/app/tests/api/api_v1/test_user.py | 112 + .../backend/app/app/tests/conftest.py | 13 + .../backend/app/app/tests/crud/__init__.py | 0 .../app/app/tests/crud/test_get_ids.py | 7 + .../backend/app/app/tests/crud/test_user.py | 105 + .../backend/app/app/tests/utils/__init__.py | 0 .../backend/app/app/tests/utils/user.py | 13 + .../backend/app/app/tests/utils/utils.py | 31 + .../backend/app/app/tests_pre_start.py | 35 + .../backend/app/app/utils.py | 126 + .../backend/app/app/worker.py | 19 + .../backend/app/backend-live.sh | 2 + .../backend/app/backend-start.sh | 27 + .../backend/app/prestart.sh | 4 + .../backend/app/scripts/lint.sh | 7 + .../backend/app/tests-start.sh | 6 + .../backend/app/worker-start.sh | 6 + .../backend/backend.dockerfile | 19 + .../backend/celeryworker.dockerfile | 23 + .../backend/tests.dockerfile | 24 + .../cookiecutter-config-file.yml | 31 + .../docker-compose.deploy.build.yml | 15 + .../docker-compose.deploy.command.yml | 11 + .../docker-compose.deploy.images.yml | 8 + .../docker-compose.deploy.labels.yml | 66 + .../docker-compose.deploy.networks.yml | 18 + ...ocker-compose.deploy.volumes-placement.yml | 17 + .../docker-compose.dev.build.yml | 25 + .../docker-compose.dev.command.yml | 12 + .../docker-compose.dev.env.yml | 14 + .../docker-compose.dev.labels.yml | 19 + .../docker-compose.dev.networks.yml | 7 + .../docker-compose.dev.ports.yml | 15 + .../docker-compose.dev.volumes.yml | 11 + .../docker-compose.shared.admin.yml | 16 + .../docker-compose.shared.base-images.yml | 6 + .../docker-compose.shared.depends.yml | 9 + .../docker-compose.shared.env.yml | 20 + .../docker-compose.test.yml | 17 + {{cookiecutter.project_slug}}/env-backend.env | 15 + {{cookiecutter.project_slug}}/env-flower.env | 3 + {{cookiecutter.project_slug}}/env-pgadmin.env | 3 + .../env-postgres.env | 4 + .../frontend/.dockerignore | 1 + {{cookiecutter.project_slug}}/frontend/.env | 10 + .../frontend/.gitignore | 21 + .../frontend/Dockerfile | 27 + .../frontend/README.md | 31 + .../frontend/babel.config.js | 10 + .../frontend/package-lock.json | 13888 ++++++++++++++++ .../frontend/package.json | 73 + .../frontend/public/favicon.ico | Bin 0 -> 1150 bytes .../img/icons/android-chrome-192x192.png | Bin 0 -> 9416 bytes .../img/icons/android-chrome-512x512.png | Bin 0 -> 29808 bytes .../img/icons/apple-touch-icon-120x120.png | Bin 0 -> 3369 bytes .../img/icons/apple-touch-icon-152x152.png | Bin 0 -> 4046 bytes .../img/icons/apple-touch-icon-180x180.png | Bin 0 -> 4678 bytes .../img/icons/apple-touch-icon-60x60.png | Bin 0 -> 1491 bytes .../img/icons/apple-touch-icon-76x76.png | Bin 0 -> 1823 bytes .../public/img/icons/apple-touch-icon.png | Bin 0 -> 4678 bytes .../public/img/icons/favicon-16x16.png | Bin 0 -> 799 bytes .../public/img/icons/favicon-32x32.png | Bin 0 -> 1271 bytes .../img/icons/msapplication-icon-144x144.png | Bin 0 -> 1169 bytes .../public/img/icons/mstile-150x150.png | Bin 0 -> 4282 bytes .../public/img/icons/safari-pinned-tab.svg | 149 + .../frontend/public/index.html | 21 + .../frontend/public/manifest.json | 20 + .../frontend/public/robots.txt | 2 + .../frontend/src/App.vue | 42 + .../frontend/src/api.ts | 48 + .../frontend/src/assets/logo.png | Bin 0 -> 6849 bytes .../frontend/src/component-hooks.ts | 8 + .../src/components/NotificationsManager.vue | 75 + .../src/components/RouterComponent.vue | 11 + .../frontend/src/components/UploadButton.vue | 34 + .../frontend/src/env.ts | 14 + .../frontend/src/interfaces/index.ts | 27 + .../frontend/src/main.ts | 19 + .../frontend/src/plugins/vee-validate.ts | 4 + .../frontend/src/plugins/vuetify.ts | 6 + .../frontend/src/registerServiceWorker.ts | 26 + .../frontend/src/router.ts | 97 + .../frontend/src/shims-tsx.d.ts | 13 + .../frontend/src/shims-vue.d.ts | 4 + .../src/store/admin/accessors/commit.ts | 10 + .../src/store/admin/accessors/dispatch.ts | 11 + .../src/store/admin/accessors/index.ts | 3 + .../src/store/admin/accessors/read.ts | 10 + .../frontend/src/store/admin/actions.ts | 64 + .../frontend/src/store/admin/getters.ts | 12 + .../frontend/src/store/admin/index.ts | 16 + .../frontend/src/store/admin/mutations.ts | 16 + .../frontend/src/store/admin/state.ts | 6 + .../frontend/src/store/index.ts | 19 + .../src/store/main/accessors/commit.ts | 15 + .../src/store/main/accessors/dispatch.ts | 20 + .../src/store/main/accessors/index.ts | 3 + .../frontend/src/store/main/accessors/read.ts | 15 + .../frontend/src/store/main/actions.ts | 163 + .../frontend/src/store/main/getters.ts | 16 + .../frontend/src/store/main/index.ts | 21 + .../frontend/src/store/main/mutations.ts | 30 + .../frontend/src/store/main/state.ts | 17 + .../frontend/src/store/state.ts | 5 + .../frontend/src/utils.ts | 5 + .../frontend/src/views/Login.vue | 57 + .../frontend/src/views/PasswordRecovery.vue | 52 + .../frontend/src/views/ResetPassword.vue | 88 + .../frontend/src/views/main/Dashboard.vue | 35 + .../frontend/src/views/main/Main.vue | 187 + .../frontend/src/views/main/Start.vue | 37 + .../frontend/src/views/main/admin/Admin.vue | 33 + .../src/views/main/admin/AdminUsers.vue | 83 + .../src/views/main/admin/CreateUser.vue | 110 + .../src/views/main/admin/EditUser.vue | 136 + .../src/views/main/profile/UserProfile.vue | 51 + .../views/main/profile/UserProfileEdit.vue | 79 + .../main/profile/UserProfileEditPassword.vue | 82 + .../frontend/tests/unit/upload-button.spec.ts | 15 + .../frontend/tsconfig.json | 41 + .../frontend/tslint.json | 19 + .../frontend/vue.config.js | 35 + .../scripts/build-push.sh | 10 + .../scripts/build.sh | 13 + .../scripts/deploy.sh | 24 + .../scripts/test-local.sh | 30 + {{cookiecutter.project_slug}}/scripts/test.sh | 19 + 198 files changed, 21022 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 cookiecutter.json create mode 100644 screenshot.png create mode 100644 scripts/discard-dev-files.sh create mode 100644 scripts/generate_cookiecutter_config.py create mode 100644 test.sh create mode 100644 testing-config.yml create mode 100644 {{cookiecutter.project_slug}}/.env create mode 100755 {{cookiecutter.project_slug}}/.gitignore create mode 100644 {{cookiecutter.project_slug}}/.gitlab-ci.yml create mode 100644 {{cookiecutter.project_slug}}/README.md create mode 100644 {{cookiecutter.project_slug}}/backend/.gitignore create mode 100644 {{cookiecutter.project_slug}}/backend/app/Pipfile create mode 100644 {{cookiecutter.project_slug}}/backend/app/Pipfile.lock create mode 100755 {{cookiecutter.project_slug}}/backend/app/alembic/README create mode 100755 {{cookiecutter.project_slug}}/backend/app/alembic/env.py create mode 100755 {{cookiecutter.project_slug}}/backend/app/alembic/script.py.mako create mode 100755 {{cookiecutter.project_slug}}/backend/app/alembic/versions/.keep create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/__init__.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/api/__init__.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/api/api_v1/__init__.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/api/api_v1/api.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/__init__.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/role.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/token.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/user.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/utils.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/backend_pre_start.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/celeryworker_pre_start.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/core/__init__.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/core/celery_app.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/core/config.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/core/jwt.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/core/security.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/crud/__init__.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/crud/user.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/crud/utils.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/db/__init__.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/db/base.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/db/base_class.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/db/external_session.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/db/full_text_search_utils.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/db/init_db.py create mode 100755 {{cookiecutter.project_slug}}/backend/app/app/db_models/__init__.py create mode 100755 {{cookiecutter.project_slug}}/backend/app/app/db_models/base_relations.py create mode 100755 {{cookiecutter.project_slug}}/backend/app/app/db_models/role.py create mode 100755 {{cookiecutter.project_slug}}/backend/app/app/db_models/user.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/email-templates/build/new_account.html create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/email-templates/build/reset_password.html create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/email-templates/build/test_email.html create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/email-templates/src/new_account.mjml create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/email-templates/src/reset_password.mjml create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/email-templates/src/test_email.mjml create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/main.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/models/__init__.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/models/config.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/models/msg.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/models/role.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/models/token.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/models/user.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/search_index_definitions/users.json create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/search_index_definitions/users_01.json create mode 100755 {{cookiecutter.project_slug}}/backend/app/app/tests/.gitignore create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/tests/__init__.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/tests/api/__init__.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/__init__.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/test_celery.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/test_token.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/test_user.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/tests/conftest.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/tests/crud/__init__.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/tests/crud/test_get_ids.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/tests/crud/test_user.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/tests/utils/__init__.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/tests/utils/user.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/tests/utils/utils.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/tests_pre_start.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/utils.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/app/worker.py create mode 100644 {{cookiecutter.project_slug}}/backend/app/backend-live.sh create mode 100644 {{cookiecutter.project_slug}}/backend/app/backend-start.sh create mode 100644 {{cookiecutter.project_slug}}/backend/app/prestart.sh create mode 100644 {{cookiecutter.project_slug}}/backend/app/scripts/lint.sh create mode 100644 {{cookiecutter.project_slug}}/backend/app/tests-start.sh create mode 100644 {{cookiecutter.project_slug}}/backend/app/worker-start.sh create mode 100644 {{cookiecutter.project_slug}}/backend/backend.dockerfile create mode 100644 {{cookiecutter.project_slug}}/backend/celeryworker.dockerfile create mode 100644 {{cookiecutter.project_slug}}/backend/tests.dockerfile create mode 100644 {{cookiecutter.project_slug}}/cookiecutter-config-file.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.deploy.build.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.deploy.command.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.deploy.images.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.deploy.labels.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.deploy.networks.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.deploy.volumes-placement.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.dev.build.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.dev.command.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.dev.env.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.dev.labels.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.dev.networks.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.dev.ports.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.dev.volumes.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.shared.admin.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.shared.base-images.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.shared.depends.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.shared.env.yml create mode 100644 {{cookiecutter.project_slug}}/docker-compose.test.yml create mode 100644 {{cookiecutter.project_slug}}/env-backend.env create mode 100644 {{cookiecutter.project_slug}}/env-flower.env create mode 100644 {{cookiecutter.project_slug}}/env-pgadmin.env create mode 100644 {{cookiecutter.project_slug}}/env-postgres.env create mode 100755 {{cookiecutter.project_slug}}/frontend/.dockerignore create mode 100644 {{cookiecutter.project_slug}}/frontend/.env create mode 100644 {{cookiecutter.project_slug}}/frontend/.gitignore create mode 100644 {{cookiecutter.project_slug}}/frontend/Dockerfile create mode 100644 {{cookiecutter.project_slug}}/frontend/README.md create mode 100644 {{cookiecutter.project_slug}}/frontend/babel.config.js create mode 100644 {{cookiecutter.project_slug}}/frontend/package-lock.json create mode 100644 {{cookiecutter.project_slug}}/frontend/package.json create mode 100644 {{cookiecutter.project_slug}}/frontend/public/favicon.ico create mode 100644 {{cookiecutter.project_slug}}/frontend/public/img/icons/android-chrome-192x192.png create mode 100644 {{cookiecutter.project_slug}}/frontend/public/img/icons/android-chrome-512x512.png create mode 100644 {{cookiecutter.project_slug}}/frontend/public/img/icons/apple-touch-icon-120x120.png create mode 100644 {{cookiecutter.project_slug}}/frontend/public/img/icons/apple-touch-icon-152x152.png create mode 100644 {{cookiecutter.project_slug}}/frontend/public/img/icons/apple-touch-icon-180x180.png create mode 100644 {{cookiecutter.project_slug}}/frontend/public/img/icons/apple-touch-icon-60x60.png create mode 100644 {{cookiecutter.project_slug}}/frontend/public/img/icons/apple-touch-icon-76x76.png create mode 100644 {{cookiecutter.project_slug}}/frontend/public/img/icons/apple-touch-icon.png create mode 100644 {{cookiecutter.project_slug}}/frontend/public/img/icons/favicon-16x16.png create mode 100644 {{cookiecutter.project_slug}}/frontend/public/img/icons/favicon-32x32.png create mode 100644 {{cookiecutter.project_slug}}/frontend/public/img/icons/msapplication-icon-144x144.png create mode 100644 {{cookiecutter.project_slug}}/frontend/public/img/icons/mstile-150x150.png create mode 100644 {{cookiecutter.project_slug}}/frontend/public/img/icons/safari-pinned-tab.svg create mode 100644 {{cookiecutter.project_slug}}/frontend/public/index.html create mode 100644 {{cookiecutter.project_slug}}/frontend/public/manifest.json create mode 100644 {{cookiecutter.project_slug}}/frontend/public/robots.txt create mode 100644 {{cookiecutter.project_slug}}/frontend/src/App.vue create mode 100644 {{cookiecutter.project_slug}}/frontend/src/api.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/assets/logo.png create mode 100644 {{cookiecutter.project_slug}}/frontend/src/component-hooks.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/components/NotificationsManager.vue create mode 100644 {{cookiecutter.project_slug}}/frontend/src/components/RouterComponent.vue create mode 100644 {{cookiecutter.project_slug}}/frontend/src/components/UploadButton.vue create mode 100644 {{cookiecutter.project_slug}}/frontend/src/env.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/interfaces/index.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/main.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/plugins/vee-validate.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/plugins/vuetify.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/registerServiceWorker.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/router.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/shims-tsx.d.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/shims-vue.d.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/admin/accessors/commit.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/admin/accessors/dispatch.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/admin/accessors/index.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/admin/accessors/read.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/admin/actions.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/admin/getters.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/admin/index.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/admin/mutations.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/admin/state.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/index.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/main/accessors/commit.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/main/accessors/dispatch.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/main/accessors/index.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/main/accessors/read.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/main/actions.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/main/getters.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/main/index.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/main/mutations.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/main/state.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/store/state.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/utils.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/src/views/Login.vue create mode 100644 {{cookiecutter.project_slug}}/frontend/src/views/PasswordRecovery.vue create mode 100644 {{cookiecutter.project_slug}}/frontend/src/views/ResetPassword.vue create mode 100644 {{cookiecutter.project_slug}}/frontend/src/views/main/Dashboard.vue create mode 100644 {{cookiecutter.project_slug}}/frontend/src/views/main/Main.vue create mode 100644 {{cookiecutter.project_slug}}/frontend/src/views/main/Start.vue create mode 100644 {{cookiecutter.project_slug}}/frontend/src/views/main/admin/Admin.vue create mode 100644 {{cookiecutter.project_slug}}/frontend/src/views/main/admin/AdminUsers.vue create mode 100644 {{cookiecutter.project_slug}}/frontend/src/views/main/admin/CreateUser.vue create mode 100644 {{cookiecutter.project_slug}}/frontend/src/views/main/admin/EditUser.vue create mode 100644 {{cookiecutter.project_slug}}/frontend/src/views/main/profile/UserProfile.vue create mode 100644 {{cookiecutter.project_slug}}/frontend/src/views/main/profile/UserProfileEdit.vue create mode 100644 {{cookiecutter.project_slug}}/frontend/src/views/main/profile/UserProfileEditPassword.vue create mode 100644 {{cookiecutter.project_slug}}/frontend/tests/unit/upload-button.spec.ts create mode 100644 {{cookiecutter.project_slug}}/frontend/tsconfig.json create mode 100644 {{cookiecutter.project_slug}}/frontend/tslint.json create mode 100644 {{cookiecutter.project_slug}}/frontend/vue.config.js create mode 100644 {{cookiecutter.project_slug}}/scripts/build-push.sh create mode 100644 {{cookiecutter.project_slug}}/scripts/build.sh create mode 100644 {{cookiecutter.project_slug}}/scripts/deploy.sh create mode 100644 {{cookiecutter.project_slug}}/scripts/test-local.sh create mode 100644 {{cookiecutter.project_slug}}/scripts/test.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..da5f752 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.vscode +testing-project +docker-stack.yml +.mypy_cache diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..2a0fec7 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,12 @@ +sudo: required + +language: python + +install: + - pip install cookiecutter + +services: + - docker + +script: +- bash ./test.sh diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f11987b --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Sebastián Ramírez + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..f6a1a5a --- /dev/null +++ b/README.md @@ -0,0 +1,126 @@ +# Full Stack Flask and PostgreSQL - Base Project Generator + +[![Build Status](https://travis-ci.org/tiangolo/full-stack.svg?branch=master)](https://travis-ci.org/tiangolo/full-stack) + +Generate a backend and frontend stack using Python, including interactive API documentation. + +[![Screenshot](screenshot.png)](https://github.com/tiangolo/full-stack) + +## Features + +* Full **Docker** integration (Docker based) +* Docker Swarm Mode deployment +* **Docker Compose** integration and optimization for local development +* **Production ready** Python web server using Nginx and uWSGI +* Python **Flask** backend with: + * **Flask-apispec**: Swagger live documentation generation + * **Marshmallow**: model and data serialization (convert model objects to JSON) + * **Webargs**: parse, validate and document inputs to the endpoint / route + * **Secure password** hashing by default + * **JWT token** authentication + * **SQLAlchemy** models (independent of Flask extensions, so they can be used with Celery workers directly) + * Basic starting models for users and groups (modify and remove as you need) + * **Alembic** migrations + * **CORS** (Cross Origin Resource Sharing) +* **Celery** worker that can import and use models and code from the rest of the backend selectively (you don't have to install the complete app in each worker) +* REST backend tests based on **Pytest**, integrated with Docker, so you can test the full API interaction, independent on the database. As it runs in Docker, it can build a new data store from scratch each time (so you can use ElasticSearch, MongoDB, CouchDB, or whatever you want, and just test that the API works) +* Easy Python integration with **Jupyter Kernels** for remote or in-Docker development with extensions like Atom Hydrogen or Visual Studio Code Jupyter +* Vue frontend: + * Generated with **Vue CLI** + * JWT Authentication handling + * Login view + * After login, main dashboard view + * **Vuex** + * **Vue-router** + * **Vuetify** for beautiful material design components + * **TypeScript** + * Docker server based on **Nginx** (configured to play nicely with Vue-router) + * Docker multi-stage building, so you don't need to save or commit compiled code + * Frontend tests ran at build time (can be disabled too) + * Made as modular as possible, so it works out of the box, but you can re-generate with Vue CLI or create it as you need, and re-use what you want +* **PGAdmin** for PostgreSQL database, you can modify it to use PHPMyAdmin and MySQL easily +* **Swagger-UI** for live interactive documentation +* **Flower** for Celery jobs monitoring +* Load balancing between frontend and backend with **Traefik**, so you can have both under the same domain, separated by path, but served by different containers +* Traefik integration, including Let's Encrypt **HTTPS** certificates automatic generation +* **GitLab CI** (continuous integration), including frontend and backend testing + +## How to use it + +Go to the directoy where you want to create your project and run: + +```bash +pip install cookiecutter +cookiecutter https://github.com/tiangolo/full-stack +``` + +### Generate passwords + +You will be asked to provide passwords and secret keys for several components. Open another terminal and run: + +```bash +openssl rand -hex 32 +# Outputs something like: 99d3b1f01aa639e4a76f4fc281fc834747a543720ba4c8a8648ba755aef9be7f +``` + +Copy the contents and use that as password / secret key. And run that again to generate another secure key. + + +### Input variables + +The generator (cookiecutter) will ask you for some data, you might want to have at hand before generating the project. + +The input variables, with their default values (some auto generated) are: + +* `project_name`: The name of the project +* `project_slug`: The development friendly name of the project. By default, based on the project name +* `domain_main`: The domain in where to deploy the project for production (from the branch `production`), used by the load balancer, backend, etc. By default, based on the project slug. +* `domain_staging`: The domain in where to deploy while staging (before production) (from the branch `master`). By default, based on the main domain. + +* `docker_swarm_stack_name_main`: The name of the stack while deploying to Docker in Swarm mode for production. By default, based on the domain. +* `docker_swarm_stack_name_staging`: The name of the stack while deploying to Docker in Swarm mode for staging. By default, based on the domain. + +* `secret_key`: Backend server secret key. Use the method above to generate it. +* `first_superuser`: The first superuser generated, with it you will be able to create more users, etc. By default, based on the domain. +* `first_superuser_password`: First superuser password. Use the method above to generate it. +* `backend_cors_origins`: Origins (domains, more or less) that are enabled for CORS (Cross Origin Resource Sharing). This allows a frontend in one domain (e.g. `https://dashboard.example.com`) to communicate with this backend, that could be living in another domain (e.g. `https://api.example.com`). It can also be used to allow your local frontend (with a custom `hosts` domain mapping, as described in the project's `README.md`) that could be living in `http://dev.example.com:8080` to cummunicate with the backend at `https://stag.example.com`. Notice the `http` vs `https` and the `dev.` prefix for local development vs the "staging" `stag.` prefix. By default, it includes origins for production, staging and development, with ports commonly used during local development by several popular frontend frameworks (Vue with `:8080`, React, Angular). + +* `postgres_password`: Postgres database password. Use the method above to generate it. (You could easily modify it to use MySQL, MariaDB, etc). +* `pgadmin_default_user`: PGAdmin default user, to log-in to the PGAdmin interface. +* `pgadmin_default_user_password`: PGAdmin default user password. Generate it with the method above. + +* `traefik_constraint_tag`: The tag to be used by the internal Traefik load balancer (for example, to divide requests between backend and frontend) for production. Used to separate this stack from any other stack you might have. This should identify each stack in each environment (production, staging, etc). +* `traefik_constraint_tag_staging`: The Traefik tag to be used while on staging. +* `traefik_public_network`: This assumes you have another separate publicly facing Traefik at the server / cluster level. This is the network that main Traefik lives in. +* `traefik_public_constraint_tag`: The tag that should be used by stack services that should communicate with the public. + +* `flower_auth`: Basic HTTP authentication for flower, in the form`user:password`. By default: "`root:changethis`". + +* `sentry_dsn`: Key URL (DSN) of Sentry, for live error reporting. If you are not using it yet, you should, is open source. E.g.: `https://1234abcd:5678ef@sentry.example.com/30`. + +* `docker_image_prefix`: Prefix to use for Docker image names. If you are using GitLab Docker registry it would be based on your code repository. E.g.: `git.example.com/development-team/my-awesome-project/`. +* `docker_image_backend`: Docker image name for the backend. By default, it will be based on your Docker image prefix, e.g.: `git.example.com/development-team/my-awesome-project/backend`. And depending on your environment, a different tag will be appended ( `prod`, `stag`, `branch` ). So, the final image names used will be like: `git.example.com/development-team/my-awesome-project/backend:prod`. +* `docker_image_celeryworker`: Docker image for the celery worker. By default, based on your Docker image prefix. +* `docker_image_frontend`: Docker image for the frontend. By default, based on your Docker image prefix. + +## How to deploy + +This stack can be adjusted and used with several deployment options that are compatible with Docker Compose, but it is designed to be used in a cluster controlled with pure Docker in Swarm Mode with a Traefik main load balancer proxy handling automatic HTTPS certificates, using the ideas from DockerSwarm.rocks. + +Please refer to DockerSwarm.rocks to see how to deploy such a cluster in 20 minutes. + +## More details + +After using this generator, your new project (the directory created) will contain an extensive `README.md` with instructions for development, deployment, etc. You can pre-read [the project `README.md` template here too](./{{cookiecutter.project_slug}}/README.md). + +## History + +**Note about Angular**: a previous version of this project generated a basic default Angular frontend application, but without any view or interaction with the rest of the stack (the backend API). I recently switched to Vue for frontend and used it to created the basic frontend views for this project (that didn't exist before). If you are interested in keeping the Angular version, let me know in an issue, I can create an Angular version of the project (without the current default views), then you can integrate your Angular app with the basic `Dockerfile` and additional files. + +This project was based on [senseta-os/senseta-base-project](https://github.com/senseta-os/senseta-base-project). + +As [I was the only maintainer](https://github.com/tiangolo), I'm continuing the development in this fork (https://github.com/tiangolo/full-stack). + +## License + +This project is licensed under the terms of the MIT license. diff --git a/cookiecutter.json b/cookiecutter.json new file mode 100644 index 0000000..0375448 --- /dev/null +++ b/cookiecutter.json @@ -0,0 +1,45 @@ +{ + "project_name": "Base Project", + "project_slug": "{{ cookiecutter.project_name|lower|replace(' ', '-') }}", + "domain_main": "{{cookiecutter.project_slug}}.com", + "domain_staging": "stag.{{cookiecutter.domain_main}}", + + "docker_swarm_stack_name_main": "{{cookiecutter.domain_main|replace('.', '-')}}", + "docker_swarm_stack_name_staging": "{{cookiecutter.domain_staging|replace('.', '-')}}", + + "secret_key": "changethis", + "first_superuser": "admin@{{cookiecutter.domain_main}}", + "first_superuser_password": "changethis", + "backend_cors_origins": "http://localhost, http://localhost:4200, http://localhost:3000, http://localhost:8080, https://localhost, https://localhost:4200, https://localhost:3000, https://localhost:8080, http://dev.{{cookiecutter.domain_main}}, https://{{cookiecutter.domain_staging}}, https://{{cookiecutter.domain_main}}, http://local.dockertoolbox.tiangolo.com, http://localhost.tiangolo.com", + "smtp_port": "587", + "smtp_host": "", + "smtp_user": "", + "smtp_password": "", + "smtp_emails_from_email": "info@{{cookiecutter.domain_main}}", + + "postgres_password": "changethis", + "pgadmin_default_user": "{{cookiecutter.first_superuser}}", + "pgadmin_default_user_password": "changethis", + + "traefik_constraint_tag": "{{cookiecutter.domain_main}}", + "traefik_constraint_tag_staging": "{{cookiecutter.domain_staging}}", + "traefik_public_network": "traefik-public", + "traefik_public_constraint_tag": "traefik-public", + + "flower_auth": "admin:{{cookiecutter.first_superuser_password}}", + + "sentry_dsn": "", + + "docker_image_prefix": "", + + "docker_image_backend": "{{cookiecutter.docker_image_prefix}}backend", + "docker_image_celeryworker": "{{cookiecutter.docker_image_prefix}}celeryworker", + "docker_image_frontend": "{{cookiecutter.docker_image_prefix}}frontend", + + "_copy_without_render": [ + "frontend/src/**/*.html", + "frontend/src/**/*.vue", + "frontend/node_modules/*", + "backend/app/app/email-templates/**" + ] +} diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..f4c06a346e9646abe788477ccef2c082a9757f6c GIT binary patch literal 86808 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 R5*q5KD696m`sLe?{|zD$_`CoB literal 0 HcmV?d00001 diff --git a/scripts/discard-dev-files.sh b/scripts/discard-dev-files.sh new file mode 100644 index 0000000..f6ae21d --- /dev/null +++ b/scripts/discard-dev-files.sh @@ -0,0 +1,13 @@ +rm -rf \{\{cookiecutter.project_slug\}\}/.git +rm -rf \{\{cookiecutter.project_slug\}\}/frontend/node_modules +rm -rf \{\{cookiecutter.project_slug\}\}/frontend/dist +git checkout \{\{cookiecutter.project_slug\}\}/README.md +git checkout \{\{cookiecutter.project_slug\}\}/.gitlab-ci.yml +git checkout \{\{cookiecutter.project_slug\}\}/cookiecutter-config-file.yml +git checkout \{\{cookiecutter.project_slug\}\}/docker-compose.deploy.networks.yml +git checkout \{\{cookiecutter.project_slug\}\}/env-backend.env +git checkout \{\{cookiecutter.project_slug\}\}/env-couchbase.env +git checkout \{\{cookiecutter.project_slug\}\}/env-flower.env +git checkout \{\{cookiecutter.project_slug\}\}/.env +git checkout \{\{cookiecutter.project_slug\}\}/frontend/.env +git checkout \{\{cookiecutter.project_slug\}\}/env-sync-gateway.env diff --git a/scripts/generate_cookiecutter_config.py b/scripts/generate_cookiecutter_config.py new file mode 100644 index 0000000..12a9a6e --- /dev/null +++ b/scripts/generate_cookiecutter_config.py @@ -0,0 +1,20 @@ +import json +from collections import OrderedDict +import oyaml as yaml +from pathlib import Path +cookie_path = Path('./cookiecutter.json') +out_path = Path('./{{cookiecutter.project_slug}}/cookiecutter-config-file.yml') + +with open(cookie_path) as f: + cookie_config = json.load(f) +config_out = OrderedDict() + +for key, value in cookie_config.items(): + if key.startswith('_'): + config_out[key] = value + else: + config_out[key] = '{{ cookiecutter.' + key + ' }}' +config_out['_template'] = './' + +with open(out_path, 'w') as out_f: + out_f.write(yaml.dump({'default_context': config_out}, line_break=None, width=200)) diff --git a/test.sh b/test.sh new file mode 100644 index 0000000..780ed88 --- /dev/null +++ b/test.sh @@ -0,0 +1,14 @@ +#! /usr/bin/env bash + +# Exit in case of error +set -e + +rm -rf ./testing-project + +cookiecutter --config-file ./testing-config.yml --no-input -f ./ + +cd ./testing-project + +bash ./scripts/test.sh + +cd ../ diff --git a/testing-config.yml b/testing-config.yml new file mode 100644 index 0000000..d117463 --- /dev/null +++ b/testing-config.yml @@ -0,0 +1,2 @@ +default_context: + "project_name": "Testing Project" diff --git a/{{cookiecutter.project_slug}}/.env b/{{cookiecutter.project_slug}}/.env new file mode 100644 index 0000000..2b6137c --- /dev/null +++ b/{{cookiecutter.project_slug}}/.env @@ -0,0 +1,16 @@ +COMPOSE_PATH_SEPARATOR=: +COMPOSE_FILE=docker-compose.test.yml:docker-compose.shared.admin.yml:docker-compose.shared.base-images.yml:docker-compose.shared.depends.yml:docker-compose.shared.env.yml:docker-compose.dev.build.yml:docker-compose.dev.command.yml:docker-compose.dev.env.yml:docker-compose.dev.labels.yml:docker-compose.dev.networks.yml:docker-compose.dev.ports.yml:docker-compose.dev.volumes.yml + +DOMAIN=localhost +# DOMAIN=local.dockertoolbox.tiangolo.com +# DOMAIN=localhost.tiangolo.com +# DOMAIN=dev.{{cookiecutter.domain_main}} + +TRAEFIK_TAG={{cookiecutter.traefik_constraint_tag}} +TRAEFIK_PUBLIC_NETWORK={{cookiecutter.traefik_public_network}} +TRAEFIK_PUBLIC_TAG={{cookiecutter.traefik_public_constraint_tag}} + +DOCKER_IMAGE_BACKEND={{cookiecutter.docker_image_backend}} +DOCKER_IMAGE_CELERYWORKER={{cookiecutter.docker_image_celeryworker}} +DOCKER_IMAGE_FRONTEND={{cookiecutter.docker_image_frontend}} +DOCKER_IMAGE_SYNC_GATEWAY={{cookiecutter.docker_image_sync_gateway}} diff --git a/{{cookiecutter.project_slug}}/.gitignore b/{{cookiecutter.project_slug}}/.gitignore new file mode 100755 index 0000000..98f27bf --- /dev/null +++ b/{{cookiecutter.project_slug}}/.gitignore @@ -0,0 +1,2 @@ +.vscode +.mypy_cache diff --git a/{{cookiecutter.project_slug}}/.gitlab-ci.yml b/{{cookiecutter.project_slug}}/.gitlab-ci.yml new file mode 100644 index 0000000..cd730c1 --- /dev/null +++ b/{{cookiecutter.project_slug}}/.gitlab-ci.yml @@ -0,0 +1,74 @@ +image: tiangolo/docker-with-compose + +before_script: + - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY + - pip install docker-auto-labels + +stages: + - test + - build + - deploy + +tests: + stage: test + script: + - sh ./scripts/test.sh + tags: + - build + - test + +build-stag: + stage: build + script: + - TAG=stag FRONTEND_ENV=staging sh ./scripts/build-push.sh + only: + - master + tags: + - build + - test + +build-prod: + stage: build + script: + - TAG=prod FRONTEND_ENV=production sh ./scripts/build-push.sh + only: + - production + tags: + - build + - test + +deploy-stag: + stage: deploy + script: + - > + DOMAIN={{cookiecutter.domain_staging}} + TRAEFIK_TAG={{cookiecutter.traefik_constraint_tag_staging}} + STACK_NAME={{cookiecutter.docker_swarm_stack_name_staging}} + TAG=stag + sh ./scripts/deploy.sh + environment: + name: staging + url: https://{{cookiecutter.domain_staging}} + only: + - master + tags: + - swarm + - stag + +deploy-prod: + stage: deploy + script: + - > + DOMAIN={{cookiecutter.domain_main}} + TRAEFIK_TAG={{cookiecutter.traefik_constraint_tag}} + STACK_NAME={{cookiecutter.docker_swarm_stack_name_main}} + TAG=prod + sh ./scripts/deploy.sh + environment: + name: production + url: https://{{cookiecutter.domain_main}} + only: + - production + tags: + - swarm + - prod diff --git a/{{cookiecutter.project_slug}}/README.md b/{{cookiecutter.project_slug}}/README.md new file mode 100644 index 0000000..a2a09ac --- /dev/null +++ b/{{cookiecutter.project_slug}}/README.md @@ -0,0 +1,755 @@ +# {{cookiecutter.project_name}} + +## Backend Requirements + +* Docker +* Docker Compose + +## Frontend Requirements + +* Node.js (with `npm`) + +## Backend local development + +* Start the stack with Docker Compose: + +```bash +docker-compose up -d +``` + +* Now you can open your browser and interact with these URLs: + +Frontend, built with Docker, with routes handled based on the path: http://localhost + +Backend, JSON based web API based on OpenAPI: http://localhost/api/ + +Automatic interactive documentation with Swagger UI (from the OpenAPI backend): http://localhost/docs + +Alternative automatic documentation with ReDoc (from the OpenAPI backend): http://localhost/redoc + +PGAdmin, PostgreSQL web administration: http://localhost:5050 + +Flower, administration of Celery tasks: http://localhost:5555 + +Traefik UI, to see how the routes are being handled by the proxy: http://localhost:8090 + +**Note**: The first time you start your stack, it might take a minute for it to be ready. While the backend waits for the database to be ready and configures everything. You can check the logs to monitor it. + +To check the logs, run: + +```bash +docker-compose logs +``` + +To check the logs of a specific service, add the name of the service, e.g.: + +```bash +docker-compose logs backend +``` + +If your Docker is not running in `localhost` (the URLs above wouldn't work) check the sections below on **Development with Docker Toolbox** and **Development with a custom IP**. + +## Backend local development, additional details + +### General workflow + +Add and modify SQLAlchemy models in `./backend/app/app/db_models/`, Pydantic models in `./backend/app/app/models` and API endpoints in `./backend/app/app/api/`. + +Add and modify tasks to the Celery worker in `./backend/app/app/worker.py`. + +If you need to install any additional package to the worker, add it to the file `./backend/app/celeryworker.dockerfile`. + +There is an `.env` file that has some Docker Compose default values that allow you to just run `docker-compose up -d` and start working, while still being able to use and share the same Docker Compose files for deployment, avoiding repetition of code and configuration as much as possible. + +### Docker Compose Override + +During development, you can change Docker Compose settings that will only affect the local development environment, in the files `docker-compose.dev.*.yml`. + +The changes to those files only affect the local development environment, not the production environment. So, you can add "temporal" changes that help the development workflow. + +For example, the directory with the backend code is mounted as a Docker "host volume" (in the file `docker-compose.dev.volumes.yml`), mapping the code you change live to the directory inside the container. That allows you to test your changes right away, without having to build the Docker image again. It should only be done during development, for production, you should build the Docker image with a recent version of the backend code. But during development, it allows you to iterate very fast. + +There is also a commented out `command` override (in the file `docker-compose.dev.command.yml`), if you want to enable it, uncomment it. It makes the backend container run a process that does "nothing", but keeps the process running. That allows you to get inside your living container and run commands inside, for example a Python interpreter to test installed dependencies, or start the development server that reloads when it detectes changes. + +To get inside the container with a `bash` session you can start the stack with: + +```bash +docker-compose up -d +``` + +and then `exec` inside the running container: + +```bash +docker-compose exec backend bash +``` + +You should see an output like: + +``` +root@7f2607af31c3:/app# +``` + +that means that you are in a `bash` session inside your container, as a `root` user, under the `/app` directory. + +There is also a script `backend-live.sh` to run the debug live reloading server. You can run that script from inside the container with: + +```bash +bash ./backend-live.sh +``` + +...it will look like: + +```bash +root@7f2607af31c3:/app# bash ./backend-live.sh +``` + +and then hit enter. That runs the debugging server that auto reloads when it detects code changes. + +Nevertheless, if it doesn't detect a change but a syntax error, it will just stop with an error. But as the container is still alive and you are in a Bash session, you can quickly restart it after fixing the error, running the same command ("up arrow" and "Enter"). + +...this previous detail is what makes it useful to have the container alive doing nothing and then, in a Bash session, make it run the debugging server. + + +### Backend tests + +To test the backend run: + +```bash +DOMAIN=backend sh ./script-test.sh +``` + +The file `./script-test.sh` has the commands to generate a testing `docker-stack.yml` file from the needed Docker Compose files, start the stack and test it. + +The tests run with Pytest, modify and add tests to `./backend/app/app/tests/`. + +If you need to install any additional package for the tests, add it to the file `./backend/app/tests.dockerfile`. + +If you use GitLab CI the tests will run automatically. + +### Live development with Python Jupyter Notebooks + +If you know about Python [Jupyter Notebooks](http://jupyter.org/), you can take advantage of them during local development. + +The `docker-compose.dev.build.yml` file sends a variable `env` with a value `dev` to the build process of the Docker image (during local development) and the `Dockerfile` has steps to then install and configure Jupyter inside your Docker container. + +So, you can enter into the Docker running container: + +```bash +docker-compose exec backend bash +``` + +And use the environment variable `$JUPYTER` to run a Jupyter Notebook with everything configured to listen on the public port (so that you can use it from your browser). + +It will output something like: + +``` +root@73e0ec1f1ae6:/app# $JUPYTER +[I 12:02:09.975 NotebookApp] Writing notebook server cookie secret to /root/.local/share/jupyter/runtime/notebook_cookie_secret +[I 12:02:10.317 NotebookApp] Serving notebooks from local directory: /app +[I 12:02:10.317 NotebookApp] The Jupyter Notebook is running at: +[I 12:02:10.317 NotebookApp] http://(73e0ec1f1ae6 or 127.0.0.1):8888/?token=f20939a41524d021fbfc62b31be8ea4dd9232913476f4397 +[I 12:02:10.317 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation). +[W 12:02:10.317 NotebookApp] No web browser found: could not locate runnable browser. +[C 12:02:10.317 NotebookApp] + + Copy/paste this URL into your browser when you connect for the first time, + to login with a token: + http://(73e0ec1f1ae6 or 127.0.0.1):8888/?token=f20939a41524d021fbfc62b31be8ea4dd9232913476f4397 +``` + +you can copy that URL and modify the "host" to be `localhost` or the domain you are using for development (e.g. `local.dockertoolbox.tiangolo.com`), in the case above, it would be, e.g.: + +``` +http://localhost:8888/token=f20939a41524d021fbfc62b31be8ea4dd9232913476f4397 +``` + + and then open it in your browser. + +You will have a full Jupyter Notebook running inside your container, that has direct access to your database by the name container name, etc. So, you can just copy your backend code and run it directly, without needing to modify it. + +If you use tools like [Hydrogen](https://github.com/nteract/hydrogen) or [Visual Studio Code Jupyter](https://donjayamanne.github.io/pythonVSCodeDocs/docs/jupyter/), you can use that same modified URL. + +### Migrations + +As during local development your app directory is mounted as a volume inside the container (set in the file `docker-compose.dev.volumes.yml`), you can also run the migrations with `alembic` commands inside the container and the migration code will be in your app directory (instead of being only inside the container). So you can add it to your git repository. + +Make sure you create a "revision" of your models and that you "upgrade" your database with that revision every time you change them. As this is what will update the tables in your database. Otherwise, your application will have errors. + +* Start an interactive session in the backend container: + +```bash +docker-compose exec backend bash +``` + +* After changing a model (for example, adding a column), inside the container, create a revision, e.g.: + +```bash +alembic revision --autogenerate -m "Add column last_name to User model" +``` + +* Commit to the git repository the files generated in the alembic directory. + +* After creating the revision, run the migration in the database (this is what will actually change the database): + +```bash +alembic upgrade head +``` + +If you don't want to use migrations at all, uncomment the line in the file at `./backend/app/app/db/init_db.py` with: + +```python +Base.metadata.create_all(bind=engine) +``` + +and comment the line in the file `prestart.sh` that contains: + +```bash +alembic upgrade head +``` + +If you don't want to start with the default models and want to remove them / modify them, from the beginning, without having any previous revision, you can remove the revision files (`.py` Python files) under `./backend/app/alembic/versions/`. And then create a first migration as described above. + +### Development with Docker Toolbox + +If you are using **Docker Toolbox** in Windows or macOS instead of **Docker for Windows** or **Docker for Mac**, Docker will be running in a VirtualBox Virtual Machine, and it will have a local IP different than `127.0.0.1`, which is the IP address for `localhost` in your machine. + +The address of your Docker Toolbox virtual machine would probably be `192.168.99.100` (that is the default). + +As this is a common case, the domain `local.dockertoolbox.tiangolo.com` points to that (private) IP, just to help with development (actually `dockertoolbox.tiangolo.com` and all its subdomains point to that IP). That way, you can start the stack in Docker Toolbox, and use that domain for development. You will be able to open that URL in Chrome and it will communicate with your local Docker Toolbox directly as if it was a cloud server, including CORS (Cross Origin Resource Sharing). + +If you used the default CORS enabled domains while generating the project, `local.dockertoolbox.tiangolo.com` was configured to be allowed. If you didn't, you will need to add it to the list in the variable `BACKEND_CORS_ORIGINS` in the `.env` file. + +To configure it in your stack, follow the section **Change the development "domain"** below, using the domain `local.dockertoolbox.tiangolo.com`. + +After performing those steps you should be able to open: http://local.dockertoolbox.tiangolo.com and it will be server by your stack in your Docker Toolbox virtual machine. + +Check all the corresponding available URLs in the section at the end. + +### Develpment in `localhost` with a custom domain + +You might want to use something different than `localhost` as the domain. For example, if you are having problems with cookies that need a subdomain, and Chrome is not allowing you to use `localhost`. + +In that case, you have two options: you could use the instructions to modify your system `hosts` file with the instructions below in **Development with a custom IP** or you can just use `localhost.tiangolo.com`, it is set up to point to `localhost` (to the IP `127.0.0.1`) and all its subdomains too. And as it is an actual domain, the browsers will store the cookies you set during development, etc. + +If you used the default CORS enabled domains while generating the project, `localhost.tiangolo.com` was configured to be allowed. If you didn't, you will need to add it to the list in the variable `BACKEND_CORS_ORIGINS` in the `.env` file. + +To configure it in your stack, follow the section **Change the development "domain"** below, using the domain `localhost.tiangolo.com`. + +After performing those steps you should be able to open: http://localhost.tiangolo.com and it will be server by your stack in `localhost`. + +Check all the corresponding available URLs in the section at the end. + +### Development with a custom IP + +If you are running Docker in an IP address different than `127.0.0.1` (`localhost`) and `192.168.99.100` (the default of Docker Toolbox), you will need to perform some additional steps. That will be the case if you are running a custom Virtual Machine, a secondary Docker Toolbox or your Docker is located in a different machine in your network. + +In that case, you will need to use a fake local domain (`dev.{{cookiecutter.domain_main}}`) and make your computer think that the domain is is served by the custom IP (e.g. `192.168.99.150`). + +If you used the default CORS enabled domains, `dev.{{cookiecutter.domain_main}}` was configured to be allowed. If you want a custom one, you need to add it to the list in the variable `BACKEND_CORS_ORIGINS` in the `.env` file. + +* Open your `hosts` file with administrative privileges using a text editor: + * **Note for Windows**: If you are in Windows, open the main Windows menu, search for "notepad", right click on it, and select the option "open as Administrator" or similar. Then click the "File" menu, "Open file", go to the directory `c:\Windows\System32\Drivers\etc\`, select the option to show "All files" instead of only "Text (.txt) files", and open the `hosts` file. + * **Note for Mac and Linux**: Your `hosts` file is probably located at `/etc/hosts`, you can edit it in a terminal running `sudo nano /etc/hosts`. + +* Additional to the contents it might have, add a new line with the custom IP (e.g. `192.168.99.150`) a space character, and your fake local domain: `dev.{{cookiecutter.domain_main}}`. + +The new line might look like: + +``` +192.168.99.100 dev.{{cookiecutter.domain_main}} +``` + +* Save the file. + * **Note for Windows**: Make sure you save the file as "All files", without an extension of `.txt`. By default, Windows tries to add the extension. Make sure the file is saved as is, without extension. + +...that will make your computer think that the fake local domain is served by that custom IP, and when you open that URL in your browser, it will talk directly to your locally running server when it is asked to go to `dev.{{cookiecutter.domain_main}}` and think that it is a remote server while it is actually running in your computer. + +To configure it in your stack, follow the section **Change the development "domain"** below, using the domain `dev.{{cookiecutter.domain_main}}`. + +After performing those steps you should be able to open: http://dev.{{cookiecutter.domain_main}} and it will be server by your stack in `localhost`. + +Check all the corresponding available URLs in the section at the end. + +### Change the development "domain" + +If you need to use your local stack with a different domain than `localhost`, you need to make sure the domain you use points to the IP where your stack is set up. See the different ways to achieve that in the sections above (i.e. using Docker Toolbox with `local.dockertoolbox.tiangolo.com`, using `localhost.tiangolo.com` or using `dev.{{cookiecutter.domain_main}}`). + +To simplify your Docker Compose setup, for example, so that the API explorer, Swagger UI, knows where is your API, you should let it know you are using that domain for development. You will need to edit 1 line in 2 files. + +* Open the file located at `./.env`. It would have a line like: + +``` +DOMAIN=localhost +``` + +* Change it to the domain you are going to use, e.g.: + +``` +DOMAIN=localhost.tiangolo.com +``` + +That variable will be used by some of the local development `docker-compose.dev.*.yml` files, for example, to tell Swagger UI to use that domain for the API. + +* Now open the file located at `./frontend/.env`. It would have a line like: + +``` +VUE_APP_DOMAIN_DEV=localhost +``` + +* Change that line to the domain you are going to use, e.g.: + +``` +VUE_APP_DOMAIN_DEV=localhost.tiangolo.com +``` + +That variable will make your frontend communicate with that domain when interacting with your backend API, when the other variable `VUE_APP_ENV` is set to `development`. + +After changing the two lines, you can re-start your stack with: + +```bash +docker-compose up -d +``` + +and check all the corresponding available URLs in the section at the end. + +## Frontend development + +* Enter the `frontend` directory, install the NPM packages and start the live server using the `npm` scripts: + +```bash +cd frontend +npm install +npm run serve +``` + +Then open your browser at http://localhost:8080 + +Notice that this live server is not running inside Docker, it is for local development, and that is the recommended workflow. Once you are happy with your frontend, you can build the frontend Docker image and start it, to test it in a production-like environment. But compiling the image at every change will not be as productive as running the local development server. + +Check the file `package.json` to see other available options. + +If you have Vue CLI installed, you can also run `vue ui` to control, configure, serve and analyse your application using a nice local web user interface. + +If you are only developing the frontend (e.g. other team members are developing the backend) and there is a staging environment already deployed, you can make your local development code use that staging API instead of a full local Docker Compose stack. + +To do that, modify the file `./frontend/.env`, there's a section with: + +``` +VUE_APP_ENV=development +# VUE_APP_ENV=staging +``` + +* Switch the comment, to: + +``` +# VUE_APP_ENV=development +VUE_APP_ENV=staging +``` + +## Deployment + +You can deploy the stack to a Docker Swarm mode cluster with a main Traefik proxy, set up using the ideas from DockerSwarm.rocks, to get automatic HTTPS certificates, etc. + +And you can use CI (continuous integration) systems to do it automatically. + +But you have to configure a couple things first. + +### Persisting Docker named volumes + +You need to make sure that each service (Docker container) that uses a volume is always deployed to the same Docker "node" in the cluster, that way it will preserve the data. Otherwise, it could be deployed to a different node each time, and each time the volume would be created in that new node before starting the service. As a result, it would look like your service was starting from scratch every time, losing all the previous data. + +That's specially important for a service running a database. But the same problem would apply if you were saving files in your main backend service (for example, if those files were uploaded by your users, or if they were created by your system). + +To solve that, you can put constraints in the services that use one or more data volumes (like databases) to make them be deployed to a Docker node with a specific label. And of course, you need to have that label assigned to one (only one) of your nodes. + + +#### Adding services with volumes + +For each service that uses a volume (databases, services with uploaded files, etc) you should have a label constraint in your `docker-compose.deploy.volumes-placement.yml` file. + +To make sure that your labels are unique per volume per stack (for examlpe, that they are not the same for `prod` and `stag`) you should prefix them with the name of your stack and then use the same name of the volume. + +Then you need to have those constraints in your deployment Docker Compose file for the services that need to be fixed with each volume. + +To be able to use different environments, like `prod` and `stag`, you should pass the name of the stack as an environment variable. Like: + +```bash +STACK_NAME={{cookiecutter.docker_swarm_stack_name_staging}} sh ./script-deploy.sh +``` + +To use and expand that environment variable inside the `docker-compose.deploy.volumes-placement.yml` files you can add the constraints to the services like: + +```yaml +version: '3' +services: + db: + volumes: + - 'app-db-data:/var/lib/postgresql/data/pgdata' + deploy: + placement: + constraints: + - node.labels.${STACK_NAME}.app-db-data == true +``` + +note the `${STACK_NAME}`. In the script `./script-deploy.sh`, that `docker-compose.deploy.volumes-placement.yml` would be converted, and saved to a file `docker-stack.yml` containing: + +```yaml +version: '3' +services: + db: + volumes: + - 'app-db-data:/var/lib/postgresql/data/pgdata' + deploy: + placement: + constraints: + - node.labels.{{cookiecutter.docker_swarm_stack_name_main}}.app-db-data == true +``` + +If you add more volumes to your stack, you need to make sure you add the corresponding constraints to the services that use that named volume. + +Then you have to create those labels in some nodes in your Docker Swarm mode cluster. You can use `docker-auto-labels` to do it automatically. + + +#### `docker-auto-labels` + +You can use [`docker-auto-labels`](https://github.com/tiangolo/docker-auto-labels) to automatically read the placement constraint labels in your Docker stack (Docker Compose file) and assign them to a random Docker node in your Swarm mode cluster if those labels don't exist yet. + +To do that, you can install `docker-auto-labels`: + +```bash +pip install docker-auto-labels +``` + +And then run it passing your `docker-stack.yml` file as a parameter: + +```bash +docker-auto-labels docker-stack.yml +``` + +You can run that command every time you deploy, right before deploying, as it doesn't modify anything if the required labels already exist. + +#### (Optionally) adding labels manually + +If you don't want to use `docker-auto-labels` or for any reason you want to manually assign the constraint labels to specific nodes in your Docker Swarm mode cluster, you can do the following: + +* First, connect via SSH to your Docker Swarm mode cluster. + +* Then check the available nodes with: + +```bash +docker node ls +``` + +you would see an output like: + +``` +ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS +nfa3d4df2df34as2fd34230rm * dog.example.com Ready Active Reachable +2c2sd2342asdfasd42342304e cat.example.com Ready Active Leader +c4sdf2342asdfasd4234234ii snake.example.com Ready Active Reachable +``` + +then chose a node from the list. For example, `dog.example.com`. + +* Add the label to that node. Use as label the name of the stack you are deploying followed by a dot (`.`) followed by the named volume, and as value, just `true`, e.g.: + +```bash +docker node update --label-add {{cookiecutter.docker_swarm_stack_name_main}}.app-db-data=true dog.example.com +``` + +* Then you need to do the same for each stack version you have. For example, for staging you could do: + +```bash +docker node update --label-add {{cookiecutter.docker_swarm_stack_name_staging}}.app-db-data=true cat.example.com +``` + +### Deploy to a Docker Swarm mode cluster + +There are 3 steps: + +1. **Build** your app images +2. Optionally, **push** your custom images to a Docker Registry +3. **Deploy** your stack + +--- + +Here are the steps in detail: + +1. **Build your app images** + +* Set these environment variables, prepended to the next command: + * `TAG=prod` + * `FRONTEND_ENV=production` +* Use the provided `script-build.sh` file with those environment variables: + +```bash +TAG=prod FRONTEND_ENV=production bash ./script-build.sh +``` + +2. **Optionally, push your images to a Docker Registry** + +**Note**: if the deployment Docker Swarm mode "cluster" has more than one server, you will have to push the images to a registry or build the images in each server, so that when each of the servers in your cluster tries to start the containers it can get the Docker images for them, pulling them from a Docker Registry or because it has them already built locally. + +If you are using a registry and pushing your images, you can omit running the previous script and instead using this one, in a single shot. + +* Set these environment variables: + * `TAG=prod` + * `FRONTEND_ENV=production` +* Use the provided `script-build-push.sh` file with those environment variables: + +```bash +TAG=prod FRONTEND_ENV=production bash ./script-build.sh +``` + +3. **Deploy your stack** + +* Set these environment variables: + * `DOMAIN={{cookiecutter.domain_main}}` + * `TRAEFIK_TAG={{cookiecutter.traefik_constraint_tag}}` + * `STACK_NAME={{cookiecutter.docker_swarm_stack_name_main}}` + * `TAG=prod` +* Use the provided `script-deploy.sh` file with those environment variables: + +```bash +DOMAIN={{cookiecutter.domain_main}} \ +TRAEFIK_TAG={{cookiecutter.traefik_constraint_tag}} \ +STACK_NAME={{cookiecutter.docker_swarm_stack_name_main}} \ +TAG=prod \ +bash ./script-deploy.sh +``` + +--- + +If you change your mind and, for example, want to deploy everything to a different domain, you only have to change the `DOMAIN` environment variable in the previous commands. If you wanted to add a different version / environment of your stack, like "`preproduction`", you would only have to set `TAG=preproduction` in your command and update these other environment variables accordingly. And it would all work, that way you could have different environments and deployments of the same app in the same cluster. + +#### Deployment Technical Details + +For the 3 steps (build, push, deploy) you need a generated `docker-stack.yml`, it is generated using the `docker-compose` command with some of the `docker-compose.*.yml` files. As each of these steps uses different `docker-compose.*.yml` files, the generated `docker-stack.yml` file is slightly different. But it's all generated by the scripts. + +You can do the process by hand based on those same scripts if you wanted. The general structure of the scripts is like this: + +```bash +# Use the environment variables passed to this script, as TAG and FRONTEND_ENV +# And re-create those variables as environment variables for the next command +TAG=${TAG} \ +# Set the environment variable FRONTEND_ENV to the same value passed to this script with +# a default value of "production" if nothing else was passed +FRONTEND_ENV=${FRONTEND_ENV-production} \ +# The actual comand that does the work: docker-compose +docker-compose \ +# Pass the files that should be used at this stage, the set of files changes in each script / each stage +-f docker-compose.deploy.build.yml \ +-f docker-compose.deploy.images.yml \ +# Use the docker-compose sub command named "config", it just uses the docker-compose.*.yml files passed +# to it and prints their combined contents +# Put those contents in a file "docker-stack.yml", with ">" +config > docker-stack.yml + +# The previous only generated a docker-stack.yml file, but didn't do anything with it +# Now this command uses that same file and does some operation with it, in this case, build it +docker-compose -f docker-stack.yml build +``` + +### Continuous Integration / Continuous Delivery + +If you use GitLab CI, the included `.gitlab-ci.yml` can automatically deploy it. You may need to update it according to your GitLab configurations. + +If you use any other CI / CD provider, you can base your deployment from that `.gitlab-ci.yml` file, as all the actual script steps are performed in `bash` scripts that you can easily re-use. + +GitLab CI is configured assuming 2 environments following GitLab flow: + +* `prod` (production) from the `production` branch. +* `stag` (staging) from the `master` branch. + +If you need to add more environments, for example, you could imagine using a client-approved `preprod` branch, you can just copy the configurations in `.gitlab-ci.yml` for `stag` and rename the corresponding variables. All the Docker Compose files are configured to support as many environments as you need, so that you only need to modify `.gitlab-ci.yml` (or whichever CI system configuration you are using). + + +## Docker Compose files + +There are several Docker Compose files, each with a specific purpose. + +They are designed to support several "stages", like development, building, testing, and deployment. Also, allowing the deployment to different environments like staging and production (and you can add more environments very easily). + +They are designed to have the minimum repetition of code and configurations, so that if you need to change something, you have to change it in the minimum amount of places. That's why several of the files use environment variables that get auto-expanded. That way, if for example, you want to use a different domain, you can call the `docker-compose` command with a different `DOMAIN` environment variable instead of having to change the domain in several places inside the Docker Compose files. + +Also, if you want to have another deployment environment, say `preprod`, you just have to change environment variables, but you can keep using the same Docker Compose files. + +Because of that, for each "stage" (development, building, testing, deployment) you would use a different set of Docker Compose files. + +But you probably don't have to worry about the different files, for building, testing and deployment, you would probably use a CI system (like GitLab CI) and the different configured files would be already set there. + +And for development, there's a `.env` file that will be automatically used by `docker-compose` locally, with the default configurations already set for local development. Including environment variables. So, for local development you can just run: + +```bash +docker-compose up -d +``` + +and it will do the right thing. + +They are also separated by the common tasks and functionalities they solve, and they are named accordinly. So, although there are many Docker Compose files, each one has a name that shows what should be in there, and the contents tend to be small and specific. That makes it easier to modify, or add configurations, as you can go directly to the relevant file. + +The `docker-compose.deploy.*.yml` files are only used at deployment, being it to production or any other environment. They build the images in production mode (not installing debugging packages), set configurations for Docker Swarm mode, etc. + +The `docker-compose.dev.*.yml` files are only used during development. They have overrides and tools for development, as mounting app volumes directly inside the container to iterate fast, map ports directly to your machine, install debugging packages, etc. + +The `docker-compose.test.yml` file is used for testing, during development and in a CI environment running tests, but not used in deployment to production (or staging or any other deployment environment of the final code). + +The `docker-compose.shared.*.yml` files are used at several stages and contain stuff shared by several stages: development, testing, deployment. They have things like the databases or the environment variables, that are used by all the main services / containers, during development, testing and deployment. The file for `admin`, that has utils needed for development and production, like the Swagger UI interactive API documentation system. But this file is not used during testing (in CI environments) as this is not needed or used in that stage. + +The purpose of each Docker Compose file is: + +* `docker-compose.deploy.build.yml`: build directories and `Dockerfile`s, for deployment (the building process for development has a little difference). +* `docker-compose.deploy.command.yml`: command overrides for images only during deployment. Initially only for the main Traefik proxy, making it run in a Docker Swarm mode cluster. +* `docker-compose.deploy.images.yml`: image names to be created, with environment variables for the specific tag. +* `docker-compose.deploy.labels.yml`: labels for deployment, the configurations to make the internal Traefik proxy serve some services on specific URLs, some with basic HTTP auth, etc. Also labels used in the internal Traefik proxy container to make it talk to the public Traefik proxy (outside of this stack) and make it send requests for this domain, generate HTTPS certificates, etc. +* `docker-compose.deploy.networks.yml`: networks that have to be used and shared by containers that need to be able to talk to the public Traefik proxy (when a service requires a domain for itself). +* `docker-compose.deploy.volumes-placement.yml`: volume declarations, volumes used by stateful services (as databases) and volume placement constraints, to make those services always run on the node that has their volumes, even after stack updates. +* `docker-compose.dev.build.yml`: build directories and `Dockerfile`s, for local development, sets a built-time argument that then is used in the `Dockerfile`s to install and configure helper tools exclusively for development. +* `docker-compose.dev.command.yml`: command overrides for local development. To tell the internal Traefik proxy to work with a local Docker in the host instead of a Docker Swarm mode cluster. And (commented out but ready to be used) overrides to make the containers run an infinite loop while keeping alive to be able to run the development server manually or do any other interactive work. +* `docker-compose.dev.env.yml`: development environment variable overrides. +* `docker-compose.dev.labels.yml`: local development labels, to be used by the local development Traefik proxy. They have to be declared in a different place than for deployment. +* `docker-compose.dev.networks.yml`: local development networks, to enable interactively talking to the backend. +* `docker-compose.dev.ports.yml`: local development port mappings. +* `docker-compose.dev.volumes.yml`: local development mounted volumes, mainly to map the development code directory inside the container, for fast development without needing to re-build the images. +* `docker-compose.shared.admin.yml`: additional services for administration or utilities with their configurations, like PGAdmin and Swagger, that are not needed during testing and use external images (don't need to be built or create images). +* `docker-compose.shared.base-images.yml`: base Docker images used without modification for shared services, as databases. Used in deployment, development, testing, etc. +* `docker-compose.shared.depends.yml`: dependencies between main services with `depends_on`, used in deployment, development, testing, etc. +* `docker-compose.shared.env.yml`: environment variables used by services, as database passwords, secret keys, etc. +* `docker-compose.test.yml`: specific additional container to be used only during testing, mainly the container that tests the backend and the APIs. + +## URLs + +These are the URLs that will be used and generated by the project. + +### Production + +Production URLs, from the branch `production`. + +Frontend: https://{{cookiecutter.domain_main}} + +Backend: https://{{cookiecutter.domain_main}}/api/ + +Automatic Interactive Docs (Swagger UI): https://{{cookiecutter.domain_main}}/docs + +Automatic Alternative Docs (ReDoc): https://{{cookiecutter.domain_main}}/redoc + +PGAdmin: https://pgadmin.{{cookiecutter.domain_main}} + +Flower: https://flower.{{cookiecutter.domain_main}} + +### Staging + +Staging URLs, from the branch `master`. + +Frontend: https://{{cookiecutter.domain_staging}} + +Backend: https://{{cookiecutter.domain_staging}}/api/ + +Automatic Interactive Docs (Swagger UI): https://{{cookiecutter.domain_staging}}/docs + +Automatic Alternative Docs (ReDoc): https://{{cookiecutter.domain_staging}}/redoc + +PGAdmin: https://pgadmin.{{cookiecutter.domain_staging}} + +Flower: https://flower.{{cookiecutter.domain_staging}} + +### Development + +Development URLs, for local development. + +Frontend: http://localhost + +Backend: http://localhost/api/ + +Automatic Interactive Docs (Swagger UI): https://localhost/docs + +Automatic Alternative Docs (ReDoc): https://localhost/redoc + +PGAdmin: http://localhost:5050 + +Flower: http://localhost:5555 + +Traefik UI: http://localhost:8090 + +### Development with Docker Toolbox + +Development URLs, for local development. + +Frontend: http://local.dockertoolbox.tiangolo.com + +Backend: http://local.dockertoolbox.tiangolo.com/api/ + +Automatic Interactive Docs (Swagger UI): https://local.dockertoolbox.tiangolo.com/docs + +Automatic Alternative Docs (ReDoc): https://local.dockertoolbox.tiangolo.com/redoc + +PGAdmin: http://local.dockertoolbox.tiangolo.com:5050 + +Flower: http://local.dockertoolbox.tiangolo.com:5555 + +Traefik UI: http://local.dockertoolbox.tiangolo.com:8090 + +### Development with a custom IP + +Development URLs, for local development. + +Frontend: http://dev.{{cookiecutter.domain_main}} + +Backend: http://dev.{{cookiecutter.domain_main}}/api/ + +Automatic Interactive Docs (Swagger UI): https://dev.{{cookiecutter.domain_main}}/docs + +Automatic Alternative Docs (ReDoc): https://dev.{{cookiecutter.domain_main}}/redoc + +PGAdmin: http://dev.{{cookiecutter.domain_main}}:5050 + +Flower: http://dev.{{cookiecutter.domain_main}}:5555 + +Traefik UI: http://dev.{{cookiecutter.domain_main}}:8090 + +### Development in localhost with a custom domain + +Development URLs, for local development. + +Frontend: http://localhost.tiangolo.com + +Backend: http://localhost.tiangolo.com/api/ + +Automatic Interactive Docs (Swagger UI): https://localhost.tiangolo.com/docs + +Automatic Alternative Docs (ReDoc): https://localhost.tiangolo.com/redoc + +PGAdmin: http://localhost.tiangolo.com:5050 + +Flower: http://localhost.tiangolo.com:5555 + +Traefik UI: http://localhost.tiangolo.com:8090 + +## Project generation and updating, or re-generating + +This project was generated using https://github.com/tiangolo/full-stack-fastapi-postgresql with: + +```bash +pip install cookiecutter +cookiecutter https://github.com/tiangolo/full-stack-fastapi-postgresql +``` + +You can check the variables used during generation in the file `cookiecutter-config-file.yml`. + +You can generate the project again with the same configurations used the first time. + +That would be useful if, for example, the project generator (`tiangolo/full-stack-fastapi-postgresql`) was updated and you want to integrate or review the changes. + +You could generate a new project with the same configurations as this one in a parallel directory. And compare the differences between the two, without having to overwrite your current code but being able to use the same variables used for your current project. + +To achieve that, the generated project includes the file `cookiecutter-config-file.yml` with the current variables used. + +You can use that file while generating a new project to reuse all those variables. + +For example, run: + +```bash +cookiecutter --config-file ./cookiecutter-config-file.yml --output-dir ../project-copy https://github.com/tiangolo/full-stack-fastapi-postgresql +``` + +That will use the file `cookiecutter-config-file.yml` in the current directory (in this project) to generate a new project inside a sibling directory `project-copy`. diff --git a/{{cookiecutter.project_slug}}/backend/.gitignore b/{{cookiecutter.project_slug}}/backend/.gitignore new file mode 100644 index 0000000..bee8a64 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/.gitignore @@ -0,0 +1 @@ +__pycache__ diff --git a/{{cookiecutter.project_slug}}/backend/app/Pipfile b/{{cookiecutter.project_slug}}/backend/app/Pipfile new file mode 100644 index 0000000..85efdfd --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/Pipfile @@ -0,0 +1,33 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[dev-packages] +mypy = "*" +black = "*" +jupyter = "*" +isort = "*" +autoflake = "*" +flake8 = "*" +pytest = "*" + +[packages] +fastapi = "*" +uvicorn = "*" +pyjwt = "*" +python-multipart = "*" +email-validator = "*" +requests = "*" +celery = "==4.2.1" +passlib = {extras = ["bcrypt"],version = "*"} +tenacity = "*" +pydantic = "*" +emails = "*" +raven = "*" + +[requires] +python_version = "3.6" + +[pipenv] +allow_prereleases = true diff --git a/{{cookiecutter.project_slug}}/backend/app/Pipfile.lock b/{{cookiecutter.project_slug}}/backend/app/Pipfile.lock new file mode 100644 index 0000000..9f8798e --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/Pipfile.lock @@ -0,0 +1,904 @@ +{ + "_meta": { + "hash": { + "sha256": "0560932caf400303d4621f7725b1e723464a3e4fe00b5a3c031739d41a5ce5fe" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.6" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "amqp": { + "hashes": [ + "sha256:16056c952e8029ce8db097edf0d7c2fe2ba9de15d30ba08aee2c5221273d8e23", + "sha256:6816eed27521293ee03aa9ace300a07215b11fee4e845588a9b863a7ba30addb" + ], + "version": "==2.4.1" + }, + "bcrypt": { + "hashes": [ + "sha256:0ba875eb67b011add6d8c5b76afbd92166e98b1f1efab9433d5dc0fafc76e203", + "sha256:21ed446054c93e209434148ef0b362432bb82bbdaf7beef70a32c221f3e33d1c", + "sha256:28a0459381a8021f57230954b9e9a65bb5e3d569d2c253c5cac6cb181d71cf23", + "sha256:2aed3091eb6f51c26b7c2fad08d6620d1c35839e7a362f706015b41bd991125e", + "sha256:2fa5d1e438958ea90eaedbf8082c2ceb1a684b4f6c75a3800c6ec1e18ebef96f", + "sha256:3a73f45484e9874252002793518da060fb11eaa76c30713faa12115db17d1430", + "sha256:3e489787638a36bb466cd66780e15715494b6d6905ffdbaede94440d6d8e7dba", + "sha256:44636759d222baa62806bbceb20e96f75a015a6381690d1bc2eda91c01ec02ea", + "sha256:678c21b2fecaa72a1eded0cf12351b153615520637efcadc09ecf81b871f1596", + "sha256:75460c2c3786977ea9768d6c9d8957ba31b5fbeb0aae67a5c0e96aab4155f18c", + "sha256:8ac06fb3e6aacb0a95b56eba735c0b64df49651c6ceb1ad1cf01ba75070d567f", + "sha256:8fdced50a8b646fff8fa0e4b1c5fd940ecc844b43d1da5a980cb07f2d1b1132f", + "sha256:9b2c5b640a2da533b0ab5f148d87fb9989bf9bcb2e61eea6a729102a6d36aef9", + "sha256:a9083e7fa9adb1a4de5ac15f9097eb15b04e2c8f97618f1b881af40abce382e1", + "sha256:b7e3948b8b1a81c5a99d41da5fb2dc03ddb93b5f96fcd3fd27e643f91efa33e1", + "sha256:b998b8ca979d906085f6a5d84f7b5459e5e94a13fc27c28a3514437013b6c2f6", + "sha256:dd08c50bc6f7be69cd7ba0769acca28c846ec46b7a8ddc2acf4b9ac6f8a7457e", + "sha256:de5badee458544ab8125e63e39afeedfcf3aef6a6e2282ac159c95ae7472d773", + "sha256:ede2a87333d24f55a4a7338a6ccdccf3eaa9bed081d1737e0db4dbd1a4f7e6b6" + ], + "version": "==3.1.6" + }, + "billiard": { + "hashes": [ + "sha256:42d9a227401ac4fba892918bba0a0c409def5435c4b483267ebfe821afaaba0e" + ], + "version": "==3.5.0.5" + }, + "cachetools": { + "hashes": [ + "sha256:219b7dc6024195b6f2bc3d3f884d1fef458745cd323b04165378622dcc823852", + "sha256:9efcc9fab3b49ab833475702b55edd5ae07af1af7a4c627678980b45e459c460" + ], + "version": "==3.1.0" + }, + "celery": { + "hashes": [ + "sha256:77dab4677e24dc654d42dfbdfed65fa760455b6bb563a0877ecc35f4cfcfc678", + "sha256:ad7a7411772b80a4d6c64f2f7f723200e39fb66cf614a7fdfab76d345acc7b13" + ], + "index": "pypi", + "version": "==4.2.1" + }, + "certifi": { + "hashes": [ + "sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7", + "sha256:993f830721089fef441cdfeb4b2c8c9df86f0c63239f06bd025a76a7daddb033" + ], + "version": "==2018.11.29" + }, + "cffi": { + "hashes": [ + "sha256:151b7eefd035c56b2b2e1eb9963c90c6302dc15fbd8c1c0a83a163ff2c7d7743", + "sha256:1553d1e99f035ace1c0544050622b7bc963374a00c467edafac50ad7bd276aef", + "sha256:1b0493c091a1898f1136e3f4f991a784437fac3673780ff9de3bcf46c80b6b50", + "sha256:2ba8a45822b7aee805ab49abfe7eec16b90587f7f26df20c71dd89e45a97076f", + "sha256:3bb6bd7266598f318063e584378b8e27c67de998a43362e8fce664c54ee52d30", + "sha256:3c85641778460581c42924384f5e68076d724ceac0f267d66c757f7535069c93", + "sha256:3eb6434197633b7748cea30bf0ba9f66727cdce45117a712b29a443943733257", + "sha256:495c5c2d43bf6cebe0178eb3e88f9c4aa48d8934aa6e3cddb865c058da76756b", + "sha256:4c91af6e967c2015729d3e69c2e51d92f9898c330d6a851bf8f121236f3defd3", + "sha256:57b2533356cb2d8fac1555815929f7f5f14d68ac77b085d2326b571310f34f6e", + "sha256:770f3782b31f50b68627e22f91cb182c48c47c02eb405fd689472aa7b7aa16dc", + "sha256:79f9b6f7c46ae1f8ded75f68cf8ad50e5729ed4d590c74840471fc2823457d04", + "sha256:7a33145e04d44ce95bcd71e522b478d282ad0eafaf34fe1ec5bbd73e662f22b6", + "sha256:857959354ae3a6fa3da6651b966d13b0a8bed6bbc87a0de7b38a549db1d2a359", + "sha256:87f37fe5130574ff76c17cab61e7d2538a16f843bb7bca8ebbc4b12de3078596", + "sha256:95d5251e4b5ca00061f9d9f3d6fe537247e145a8524ae9fd30a2f8fbce993b5b", + "sha256:9d1d3e63a4afdc29bd76ce6aa9d58c771cd1599fbba8cf5057e7860b203710dd", + "sha256:a36c5c154f9d42ec176e6e620cb0dd275744aa1d804786a71ac37dc3661a5e95", + "sha256:a6a5cb8809091ec9ac03edde9304b3ad82ad4466333432b16d78ef40e0cce0d5", + "sha256:ae5e35a2c189d397b91034642cb0eab0e346f776ec2eb44a49a459e6615d6e2e", + "sha256:b0f7d4a3df8f06cf49f9f121bead236e328074de6449866515cea4907bbc63d6", + "sha256:b75110fb114fa366b29a027d0c9be3709579602ae111ff61674d28c93606acca", + "sha256:ba5e697569f84b13640c9e193170e89c13c6244c24400fc57e88724ef610cd31", + "sha256:be2a9b390f77fd7676d80bc3cdc4f8edb940d8c198ed2d8c0be1319018c778e1", + "sha256:ca1bd81f40adc59011f58159e4aa6445fc585a32bb8ac9badf7a2c1aa23822f2", + "sha256:d5d8555d9bfc3f02385c1c37e9f998e2011f0db4f90e250e5bc0c0a85a813085", + "sha256:e55e22ac0a30023426564b1059b035973ec82186ddddbac867078435801c7801", + "sha256:e90f17980e6ab0f3c2f3730e56d1fe9bcba1891eeea58966e89d352492cc74f4", + "sha256:ecbb7b01409e9b782df5ded849c178a0aa7c906cf8c5a67368047daab282b184", + "sha256:ed01918d545a38998bfa5902c7c00e0fee90e957ce036a4000a88e3fe2264917", + "sha256:edabd457cd23a02965166026fd9bfd196f4324fe6032e866d0f3bd0301cd486f", + "sha256:fdf1c1dc5bafc32bc5d08b054f94d659422b05aba244d6be4ddc1c72d9aa70fb" + ], + "version": "==1.11.5" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "version": "==3.0.4" + }, + "click": { + "hashes": [ + "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", + "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" + ], + "version": "==7.0" + }, + "cssselect": { + "hashes": [ + "sha256:066d8bc5229af09617e24b3ca4d52f1f9092d9e061931f4184cd572885c23204", + "sha256:3b5103e8789da9e936a68d993b70df732d06b8bb9a337a05ed4eb52c17ef7206" + ], + "version": "==1.0.3" + }, + "cssutils": { + "hashes": [ + "sha256:a2fcf06467553038e98fea9cfe36af2bf14063eb147a70958cfcaa8f5786acaf", + "sha256:c74dbe19c92f5052774eadb15136263548dd013250f1ed1027988e7fef125c8d" + ], + "version": "==1.0.2" + }, + "dataclasses": { + "hashes": [ + "sha256:454a69d788c7fda44efd71e259be79577822f5e3f53f029a22d08004e951dc9f", + "sha256:6988bd2b895eef432d562370bb707d540f32f7360ab13da45340101bc2307d84" + ], + "markers": "python_version < '3.7'", + "version": "==0.6" + }, + "dnspython": { + "hashes": [ + "sha256:36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01", + "sha256:f69c21288a962f4da86e56c4905b49d11aba7938d3d740e80d9e366ee4f1632d" + ], + "version": "==1.16.0" + }, + "email-validator": { + "hashes": [ + "sha256:ddc4b5b59fa699bb10127adcf7ad4de78fde4ec539a072b104b8bb16da666ae5" + ], + "index": "pypi", + "version": "==1.0.3" + }, + "emails": { + "hashes": [ + "sha256:2d93bb09539d65a16cf1f68db4ffd0f7f45067633e950866e8a4ef89a7c290ec", + "sha256:fcc02567a528eae6b66d2a5c20ce7a0326e4f6b201bc8ae302f89413164db06a" + ], + "index": "pypi", + "version": "==0.5.15" + }, + "fastapi": { + "hashes": [ + "sha256:932d7e3d13ef1541b0eeb78576c98a68f15552c44a40ae4fb5816b39184d2307", + "sha256:b6485bfbf585c6cb944a9a12ae0c29408f046c32ff0341bd46c6e2f1502d214d" + ], + "index": "pypi", + "version": "==0.2.0" + }, + "h11": { + "hashes": [ + "sha256:acca6a44cb52a32ab442b1779adf0875c443c689e9e028f8d831a3769f9c5208", + "sha256:f2b1ca39bfed357d1f19ac732913d5f9faa54a5062eca7d2ec3a916cfb7ae4c7" + ], + "version": "==0.8.1" + }, + "httptools": { + "hashes": [ + "sha256:04c7703bbef0e8ca28b09811547352b8c7c20549eab70dc24e536bb24fd2b7c5" + ], + "version": "==0.0.11" + }, + "idna": { + "hashes": [ + "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", + "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + ], + "version": "==2.8" + }, + "kombu": { + "hashes": [ + "sha256:529df9e0ecc0bad9fc2b376c3ce4796c41b482cf697b78b71aea6ebe7ca353c8", + "sha256:7a2cbed551103db9a4e2efafe9b63222e012a61a18a881160ad797b9d4e1d0a1" + ], + "version": "==4.3.0" + }, + "lxml": { + "hashes": [ + "sha256:0537eee4902e8bf4f41bfee8133f7edf96533dd175930a12086d6a40d62376b2", + "sha256:0562ec748abd230ab87d73384e08fa784f9b9cee89e28696087d2d22c052cc27", + "sha256:09e91831e749fbf0f24608694e4573be0ef51430229450c39c83176cc2e2d353", + "sha256:1ae4c0722fc70c0d4fba43ae33c2885f705e96dce1db41f75ae14a2d2749b428", + "sha256:1c630c083d782cbaf1f7f37f6cac87bda9cff643cf2803a5f180f30d97955cef", + "sha256:2fe74e3836bd8c0fa7467ffae05545233c7f37de1eb765cacfda15ad20c6574a", + "sha256:37af783c2667ead34a811037bda56a0b142ac8438f7ed29ae93f82ddb812fbd6", + "sha256:3f2d9eafbb0b24a33f56acd16f39fc935756524dcb3172892721c54713964c70", + "sha256:47d8365a8ef14097aa4c65730689be51851b4ade677285a3b2daa03b37893e26", + "sha256:510e904079bc56ea784677348e151e1156040dbfb736f1d8ea4b9e6d0ab2d9f4", + "sha256:58d0851da422bba31c7f652a7e9335313cf94a641aa6d73b8f3c67602f75b593", + "sha256:7940d5c2185ffb989203dacbb28e6ae88b4f1bb25d04e17f94b0edd82232bcbd", + "sha256:7cf39bb3a905579836f7a8f3a45320d9eb22f16ab0c1e112efb940ced4d057a5", + "sha256:9563a23c1456c0ab550c087833bc13fcc61013a66c6420921d5b70550ea312bf", + "sha256:95b392952935947e0786a90b75cc33388549dcb19af716b525dae65b186138fc", + "sha256:983129f3fd3cef5c3cf067adcca56e30a169656c00fcc6c648629dbb850b27fa", + "sha256:a0b75b1f1854771844c647c464533def3e0a899dd094a85d1d4ed72ecaaee93d", + "sha256:b5db89cc0ef624f3a81214b7961a99f443b8c91e88188376b6b322fd10d5b118", + "sha256:c0a7751ba1a4bfbe7831920d98cee3ce748007eab8dfda74593d44079568219a", + "sha256:c0c5a7d4aafcc30c9b6d8613a362567e32e5f5b708dc41bc3a81dac56f8af8bb", + "sha256:d4d63d85eacc6cb37b459b16061e1f100d154bee89dc8d8f9a6128a5a538e92e", + "sha256:da5e7e941d6e71c9c9a717c93725cda0708c2474f532e3680ac5e39ec57d224d", + "sha256:dccad2b3c583f036f43f80ac99ee212c2fa9a45151358d55f13004d095e683b2", + "sha256:df46307d39f2aeaafa1d25309b8a8d11738b73e9861f72d4d0a092528f498baa", + "sha256:e70b5e1cb48828ddd2818f99b1662cb9226dc6f57d07fc75485405c77da17436", + "sha256:ea825562b8cd057cbc9810d496b8b5dec37a1e2fc7b27bc7c1e72ce94462a09a" + ], + "version": "==4.3.1" + }, + "passlib": { + "extras": [ + "bcrypt" + ], + "hashes": [ + "sha256:3d948f64138c25633613f303bcc471126eae67c04d5e3f6b7b8ce6242f8653e0", + "sha256:43526aea08fa32c6b6dbbbe9963c4c767285b78147b7437597f992812f69d280" + ], + "index": "pypi", + "version": "==1.7.1" + }, + "premailer": { + "hashes": [ + "sha256:93be4f197e9d2a87a8fe6b5b6a79b64070dbb523108dfaf2a415b4558fc78ec1", + "sha256:f45eb4a30485aeccc3ff19771d6614346899ec19a301931af4694f737b6035c3" + ], + "version": "==3.3.0" + }, + "pycparser": { + "hashes": [ + "sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3" + ], + "version": "==2.19" + }, + "pydantic": { + "hashes": [ + "sha256:9f023811b6cefd203c5fd8fd15a4152f04e79e531b8f676ab1244dfe06ce8024", + "sha256:edbb08b561feda505374c0f25e4b54466a0a0c702ed6b2efaabdc3890d1a82e7" + ], + "index": "pypi", + "version": "==0.18.2" + }, + "pyjwt": { + "hashes": [ + "sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e", + "sha256:8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96" + ], + "index": "pypi", + "version": "==1.7.1" + }, + "python-dateutil": { + "hashes": [ + "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", + "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" + ], + "version": "==2.8.0" + }, + "python-multipart": { + "hashes": [ + "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43" + ], + "index": "pypi", + "version": "==0.0.5" + }, + "pytz": { + "hashes": [ + "sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9", + "sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c" + ], + "version": "==2018.9" + }, + "raven": { + "hashes": [ + "sha256:3fa6de6efa2493a7c827472e984ce9b020797d0da16f1db67197bcc23c8fae54", + "sha256:44a13f87670836e153951af9a3c80405d36b43097db869a36e92809673692ce4" + ], + "index": "pypi", + "version": "==6.10.0" + }, + "requests": { + "hashes": [ + "sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e", + "sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b" + ], + "index": "pypi", + "version": "==2.21.0" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "version": "==1.12.0" + }, + "starlette": { + "hashes": [ + "sha256:7cc05c33d00db3b2ddfd7516a737544ed0a34c9dd0ced94076f29b581ce4f532" + ], + "version": "==0.10.1" + }, + "tenacity": { + "hashes": [ + "sha256:24b7f302a1caa1801e58b39ea557129c095966e64e5b1ddad3c93a6cb033e38b", + "sha256:a04b97b3bda047f912a75d110dde3e746891b5548b6bec6d157cd100f2d4afac" + ], + "index": "pypi", + "version": "==5.0.3" + }, + "urllib3": { + "hashes": [ + "sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39", + "sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22" + ], + "version": "==1.24.1" + }, + "uvicorn": { + "hashes": [ + "sha256:e84fc3b1e142cec395fb7c1d1a9f3cdc0d455037b96e1bed54b378db1121aaba" + ], + "index": "pypi", + "version": "==0.4.3" + }, + "uvloop": { + "hashes": [ + "sha256:0ff2e67b693f7d2007466952dbe312075098e8f15364fda27d16e8a7f266d74d", + "sha256:2d0029314dc87312ff8d46c3724363d847e5235403eced5d3f98da80a87f4828", + "sha256:32dcc003e1973f3db303494f5f63db11091c86a146053773d81ac5484b10c416", + "sha256:4301871418f967d0b13409f1bd10ecc7825a7f183282dcc9e19d08532e6cb2e9", + "sha256:7639188ff4466d86cfd4418cd784d1198a8cc913279fb8798a4b12a4d42ad341", + "sha256:a73649cd043f5d3e3ae471667c790a7ee2295b22fac7bedcae8705158f8ba111", + "sha256:afdf34bf507090e4c7f5108a17240982760356b8aae4edd37180ec4f94c36cbb", + "sha256:bd7a6db5dbfae0c93e27cb200bb2b9513e21a90a2d4a259b39a9b5446c4d5aa3", + "sha256:cc27e903da274f76826848832f62e1ec410a43602e1e0cd4f8db8c619b1ee93e", + "sha256:ec521d14ddcdd9f8d0075d7d1f82e9d8806f7f0a047d2e5bc737e9eddf7f930d" + ], + "version": "==0.12.0" + }, + "vine": { + "hashes": [ + "sha256:3cd505dcf980223cfaf13423d371f2e7ff99247e38d5985a01ec8264e4f2aca1", + "sha256:ee4813e915d0e1a54e5c1963fde0855337f82655678540a6bc5996bca4165f76" + ], + "version": "==1.2.0" + }, + "websockets": { + "hashes": [ + "sha256:04b42a1b57096ffa5627d6a78ea1ff7fad3bc2c0331ffc17bc32a4024da7fea0", + "sha256:08e3c3e0535befa4f0c4443824496c03ecc25062debbcf895874f8a0b4c97c9f", + "sha256:10d89d4326045bf5e15e83e9867c85d686b612822e4d8f149cf4840aab5f46e0", + "sha256:232fac8a1978fc1dead4b1c2fa27c7756750fb393eb4ac52f6bc87ba7242b2fa", + "sha256:4bf4c8097440eff22bc78ec76fe2a865a6e658b6977a504679aaf08f02c121da", + "sha256:51642ea3a00772d1e48fb0c492f0d3ae3b6474f34d20eca005a83f8c9c06c561", + "sha256:55d86102282a636e195dad68aaaf85b81d0bef449d7e2ef2ff79ac450bb25d53", + "sha256:564d2675682bd497b59907d2205031acbf7d3fadf8c763b689b9ede20300b215", + "sha256:5d13bf5197a92149dc0badcc2b699267ff65a867029f465accfca8abab95f412", + "sha256:5eda665f6789edb9b57b57a159b9c55482cbe5b046d7db458948370554b16439", + "sha256:5edb2524d4032be4564c65dc4f9d01e79fe8fad5f966e5b552f4e5164fef0885", + "sha256:79691794288bc51e2a3b8de2bc0272ca8355d0b8503077ea57c0716e840ebaef", + "sha256:7fcc8681e9981b9b511cdee7c580d5b005f3bb86b65bde2188e04a29f1d63317", + "sha256:8e447e05ec88b1b408a4c9cde85aa6f4b04f06aa874b9f0b8e8319faf51b1fee", + "sha256:90ea6b3e7787620bb295a4ae050d2811c807d65b1486749414f78cfd6fb61489", + "sha256:9e13239952694b8b831088431d15f771beace10edfcf9ef230cefea14f18508f", + "sha256:d40f081187f7b54d7a99d8a5c782eaa4edc335a057aa54c85059272ed826dc09", + "sha256:e1df1a58ed2468c7b7ce9a2f9752a32ad08eac2bcd56318625c3647c2cd2da6f", + "sha256:e98d0cec437097f09c7834a11c69d79fe6241729b23f656cfc227e93294fc242", + "sha256:f8d59627702d2ff27cb495ca1abdea8bd8d581de425c56e93bff6517134e0a9b", + "sha256:fc30cdf2e949a2225b012a7911d1d031df3d23e99b7eda7dfc982dc4a860dae9" + ], + "version": "==7.0" + } + }, + "develop": { + "appdirs": { + "hashes": [ + "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", + "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e" + ], + "version": "==1.4.3" + }, + "atomicwrites": { + "hashes": [ + "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", + "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6" + ], + "version": "==1.3.0" + }, + "attrs": { + "hashes": [ + "sha256:10cbf6e27dbce8c30807caf056c8eb50917e0eaafe86347671b57254006c3e69", + "sha256:ca4be454458f9dec299268d472aaa5a11f67a4ff70093396e1ceae9c76cf4bbb" + ], + "version": "==18.2.0" + }, + "autoflake": { + "hashes": [ + "sha256:c103e63466f11db3617167a2c68ff6a0cda35b940222920631c6eeec6b67e807" + ], + "index": "pypi", + "version": "==1.2" + }, + "backcall": { + "hashes": [ + "sha256:38ecd85be2c1e78f77fd91700c76e14667dc21e2713b63876c0eb901196e01e4", + "sha256:bbbf4b1e5cd2bdb08f915895b51081c041bac22394fdfcfdfbe9f14b77c08bf2" + ], + "version": "==0.1.0" + }, + "black": { + "hashes": [ + "sha256:817243426042db1d36617910df579a54f1afd659adb96fc5032fcf4b36209739", + "sha256:e030a9a28f542debc08acceb273f228ac422798e5215ba2a791a6ddeaaca22a5" + ], + "index": "pypi", + "version": "==18.9b0" + }, + "bleach": { + "hashes": [ + "sha256:213336e49e102af26d9cde77dd2d0397afabc5a6bf2fed985dc35b5d1e285a16", + "sha256:3fdf7f77adcf649c9911387df51254b813185e32b2c6619f690b593a617e19fa" + ], + "version": "==3.1.0" + }, + "click": { + "hashes": [ + "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", + "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" + ], + "version": "==7.0" + }, + "decorator": { + "hashes": [ + "sha256:33cd704aea07b4c28b3eb2c97d288a06918275dac0ecebdaf1bc8a48d98adb9e", + "sha256:cabb249f4710888a2fc0e13e9a16c343d932033718ff62e1e9bc93a9d3a9122b" + ], + "version": "==4.3.2" + }, + "defusedxml": { + "hashes": [ + "sha256:24d7f2f94f7f3cb6061acb215685e5125fbcdc40a857eff9de22518820b0a4f4", + "sha256:702a91ade2968a82beb0db1e0766a6a273f33d4616a6ce8cde475d8e09853b20" + ], + "version": "==0.5.0" + }, + "entrypoints": { + "hashes": [ + "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", + "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451" + ], + "version": "==0.3" + }, + "flake8": { + "hashes": [ + "sha256:c3ba1e130c813191db95c431a18cb4d20a468e98af7a77e2181b68574481ad36", + "sha256:fd9ddf503110bf3d8b1d270e8c673aab29ccb3dd6abf29bae1f54e5116ab4a91" + ], + "index": "pypi", + "version": "==3.7.5" + }, + "ipykernel": { + "hashes": [ + "sha256:0aeb7ec277ac42cc2b59ae3d08b10909b2ec161dc6908096210527162b53675d", + "sha256:0fc0bf97920d454102168ec2008620066878848fcfca06c22b669696212e292f" + ], + "version": "==5.1.0" + }, + "ipython": { + "hashes": [ + "sha256:6a9496209b76463f1dec126ab928919aaf1f55b38beb9219af3fe202f6bbdd12", + "sha256:f69932b1e806b38a7818d9a1e918e5821b685715040b48e59c657b3c7961b742" + ], + "markers": "python_version >= '3.3'", + "version": "==7.2.0" + }, + "ipython-genutils": { + "hashes": [ + "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8", + "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8" + ], + "version": "==0.2.0" + }, + "ipywidgets": { + "hashes": [ + "sha256:0f2b5cde9f272cb49d52f3f0889fdd1a7ae1e74f37b48dac35a83152780d2b7b", + "sha256:a3e224f430163f767047ab9a042fc55adbcab0c24bbe6cf9f306c4f89fdf0ba3" + ], + "version": "==7.4.2" + }, + "isort": { + "hashes": [ + "sha256:1153601da39a25b14ddc54955dbbacbb6b2d19135386699e2ad58517953b34af", + "sha256:b9c40e9750f3d77e6e4d441d8b0266cf555e7cdabdcff33c4fd06366ca761ef8", + "sha256:ec9ef8f4a9bc6f71eec99e1806bfa2de401650d996c59330782b89a5555c1497" + ], + "index": "pypi", + "version": "==4.3.4" + }, + "jedi": { + "hashes": [ + "sha256:571702b5bd167911fe9036e5039ba67f820d6502832285cde8c881ab2b2149fd", + "sha256:c8481b5e59d34a5c7c42e98f6625e633f6ef59353abea6437472c7ec2093f191" + ], + "version": "==0.13.2" + }, + "jinja2": { + "hashes": [ + "sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd", + "sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4" + ], + "version": "==2.10" + }, + "jsonschema": { + "hashes": [ + "sha256:683fe7ed58763ea0be572de5aad47cd3cc1297640916f9a8ccd222b287da7d2f", + "sha256:b42d7a292addb57370e6260bcbadb77e00a899fe6ec998c453f45893c41c658b" + ], + "version": "==3.0.0b3" + }, + "jupyter": { + "hashes": [ + "sha256:3e1f86076bbb7c8c207829390305a2b1fe836d471ed54be66a3b8c41e7f46cc7", + "sha256:5b290f93b98ffbc21c0c7e749f054b3267782166d72fa5e3ed1ed4eaf34a2b78", + "sha256:d9dc4b3318f310e34c82951ea5d6683f67bed7def4b259fafbfe4f1beb1d8e5f" + ], + "index": "pypi", + "version": "==1.0.0" + }, + "jupyter-client": { + "hashes": [ + "sha256:b5f9cb06105c1d2d30719db5ffb3ea67da60919fb68deaefa583deccd8813551", + "sha256:c44411eb1463ed77548bc2d5ec0d744c9b81c4a542d9637c7a52824e2121b987" + ], + "version": "==5.2.4" + }, + "jupyter-console": { + "hashes": [ + "sha256:308ce876354924fb6c540b41d5d6d08acfc946984bf0c97777c1ddcb42e0b2f5", + "sha256:cc80a97a5c389cbd30252ffb5ce7cefd4b66bde98219edd16bf5cb6f84bb3568" + ], + "version": "==6.0.0" + }, + "jupyter-core": { + "hashes": [ + "sha256:927d713ffa616ea11972534411544589976b2493fc7e09ad946e010aa7eb9970", + "sha256:ba70754aa680300306c699790128f6fbd8c306ee5927976cbe48adacf240c0b7" + ], + "version": "==4.4.0" + }, + "markupsafe": { + "hashes": [ + "sha256:048ef924c1623740e70204aa7143ec592504045ae4429b59c30054cb31e3c432", + "sha256:130f844e7f5bdd8e9f3f42e7102ef1d49b2e6fdf0d7526df3f87281a532d8c8b", + "sha256:19f637c2ac5ae9da8bfd98cef74d64b7e1bb8a63038a3505cd182c3fac5eb4d9", + "sha256:1b8a7a87ad1b92bd887568ce54b23565f3fd7018c4180136e1cf412b405a47af", + "sha256:1c25694ca680b6919de53a4bb3bdd0602beafc63ff001fea2f2fc16ec3a11834", + "sha256:1f19ef5d3908110e1e891deefb5586aae1b49a7440db952454b4e281b41620cd", + "sha256:1fa6058938190ebe8290e5cae6c351e14e7bb44505c4a7624555ce57fbbeba0d", + "sha256:31cbb1359e8c25f9f48e156e59e2eaad51cd5242c05ed18a8de6dbe85184e4b7", + "sha256:3e835d8841ae7863f64e40e19477f7eb398674da6a47f09871673742531e6f4b", + "sha256:4e97332c9ce444b0c2c38dd22ddc61c743eb208d916e4265a2a3b575bdccb1d3", + "sha256:525396ee324ee2da82919f2ee9c9e73b012f23e7640131dd1b53a90206a0f09c", + "sha256:52b07fbc32032c21ad4ab060fec137b76eb804c4b9a1c7c7dc562549306afad2", + "sha256:52ccb45e77a1085ec5461cde794e1aa037df79f473cbc69b974e73940655c8d7", + "sha256:5c3fbebd7de20ce93103cb3183b47671f2885307df4a17a0ad56a1dd51273d36", + "sha256:5e5851969aea17660e55f6a3be00037a25b96a9b44d2083651812c99d53b14d1", + "sha256:5edfa27b2d3eefa2210fb2f5d539fbed81722b49f083b2c6566455eb7422fd7e", + "sha256:7d263e5770efddf465a9e31b78362d84d015cc894ca2c131901a4445eaa61ee1", + "sha256:83381342bfc22b3c8c06f2dd93a505413888694302de25add756254beee8449c", + "sha256:857eebb2c1dc60e4219ec8e98dfa19553dae33608237e107db9c6078b1167856", + "sha256:98e439297f78fca3a6169fd330fbe88d78b3bb72f967ad9961bcac0d7fdd1550", + "sha256:bf54103892a83c64db58125b3f2a43df6d2cb2d28889f14c78519394feb41492", + "sha256:d9ac82be533394d341b41d78aca7ed0e0f4ba5a2231602e2f05aa87f25c51672", + "sha256:e982fe07ede9fada6ff6705af70514a52beb1b2c3d25d4e873e82114cf3c5401", + "sha256:edce2ea7f3dfc981c4ddc97add8a61381d9642dc3273737e756517cc03e84dd6", + "sha256:efdc45ef1afc238db84cb4963aa689c0408912a0239b0721cb172b4016eb31d6", + "sha256:f137c02498f8b935892d5c0172560d7ab54bc45039de8805075e19079c639a9c", + "sha256:f82e347a72f955b7017a39708a3667f106e6ad4d10b25f237396a7115d8ed5fd", + "sha256:fb7c206e01ad85ce57feeaaa0bf784b97fa3cad0d4a5737bc5295785f5c613a1" + ], + "version": "==1.1.0" + }, + "mccabe": { + "hashes": [ + "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", + "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + ], + "version": "==0.6.1" + }, + "mistune": { + "hashes": [ + "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e", + "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4" + ], + "version": "==0.8.4" + }, + "more-itertools": { + "hashes": [ + "sha256:38a936c0a6d98a38bcc2d03fdaaedaba9f412879461dd2ceff8d37564d6522e4", + "sha256:c0a5785b1109a6bd7fac76d6837fd1feca158e54e521ccd2ae8bfe393cc9d4fc", + "sha256:fe7a7cae1ccb57d33952113ff4fa1bc5f879963600ed74918f1236e212ee50b9" + ], + "version": "==5.0.0" + }, + "mypy": { + "hashes": [ + "sha256:308c274eb8482fbf16006f549137ddc0d69e5a589465e37b99c4564414363ca7", + "sha256:e80fd6af34614a0e898a57f14296d0dacb584648f0339c2e000ddbf0f4cc2f8d" + ], + "index": "pypi", + "version": "==0.670" + }, + "mypy-extensions": { + "hashes": [ + "sha256:37e0e956f41369209a3d5f34580150bcacfabaa57b33a15c0b25f4b5725e0812", + "sha256:b16cabe759f55e3409a7d231ebd2841378fb0c27a5d1994719e340e4f429ac3e" + ], + "version": "==0.4.1" + }, + "nbconvert": { + "hashes": [ + "sha256:302554a2e219bc0fc84f3edd3e79953f3767b46ab67626fdec16e38ba3f7efe4", + "sha256:5de8fb2284422272a1d45abc77c07b888127550a6d602ce619592a2b08a474ff" + ], + "version": "==5.4.1" + }, + "nbformat": { + "hashes": [ + "sha256:b9a0dbdbd45bb034f4f8893cafd6f652ea08c8c1674ba83f2dc55d3955743b0b", + "sha256:f7494ef0df60766b7cabe0a3651556345a963b74dbc16bc7c18479041170d402" + ], + "version": "==4.4.0" + }, + "notebook": { + "hashes": [ + "sha256:3ab2db8bc10e6edbd264c3c4b800bee276c99818386ee0c146d98d7e6bcf0a67", + "sha256:d908673a4010787625c8952e91a22adf737db031f2aa0793ad92f6558918a74a" + ], + "version": "==5.7.4" + }, + "pandocfilters": { + "hashes": [ + "sha256:b3dd70e169bb5449e6bc6ff96aea89c5eea8c5f6ab5e207fc2f521a2cf4a0da9" + ], + "version": "==1.4.2" + }, + "parso": { + "hashes": [ + "sha256:6ecf7244be8e7283ec9009c72d074830e7e0e611c974f813d76db0390a4e0dd6", + "sha256:8162be7570ffb34ec0b8d215d7f3b6c5fab24f51eb3886d6dee362de96b6db94" + ], + "version": "==0.3.3" + }, + "pexpect": { + "hashes": [ + "sha256:2a8e88259839571d1251d278476f3eec5db26deb73a70be5ed5dc5435e418aba", + "sha256:3fbd41d4caf27fa4a377bfd16fef87271099463e6fa73e92a52f92dfee5d425b" + ], + "markers": "sys_platform != 'win32'", + "version": "==4.6.0" + }, + "pickleshare": { + "hashes": [ + "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca", + "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56" + ], + "version": "==0.7.5" + }, + "pluggy": { + "hashes": [ + "sha256:8ddc32f03971bfdf900a81961a48ccf2fb677cf7715108f85295c67405798616", + "sha256:980710797ff6a041e9a73a5787804f848996ecaa6f8a1b1e08224a5894f2074a" + ], + "version": "==0.8.1" + }, + "prometheus-client": { + "hashes": [ + "sha256:e8c11ff5ca53de6c3d91e1510500611cafd1d247a937ec6c588a0a7cc3bef93c" + ], + "version": "==0.5.0" + }, + "prompt-toolkit": { + "hashes": [ + "sha256:88002cc618cacfda8760c4539e76c3b3f148ecdb7035a3d422c7ecdc90c2a3ba", + "sha256:c6655a12e9b08edb8cf5aeab4815fd1e1bdea4ad73d3bbf269cf2e0c4eb75d5e", + "sha256:df5835fb8f417aa55e5cafadbaeb0cf630a1e824aad16989f9f0493e679ec010" + ], + "version": "==2.0.8" + }, + "ptyprocess": { + "hashes": [ + "sha256:923f299cc5ad920c68f2bc0bc98b75b9f838b93b599941a6b63ddbc2476394c0", + "sha256:d7cc528d76e76342423ca640335bd3633420dc1366f258cb31d05e865ef5ca1f" + ], + "markers": "os_name != 'nt'", + "version": "==0.6.0" + }, + "py": { + "hashes": [ + "sha256:bf92637198836372b520efcba9e020c330123be8ce527e535d185ed4b6f45694", + "sha256:e76826342cefe3c3d5f7e8ee4316b80d1dd8a300781612ddbc765c17ba25a6c6" + ], + "version": "==1.7.0" + }, + "pycodestyle": { + "hashes": [ + "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", + "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c" + ], + "version": "==2.5.0" + }, + "pyflakes": { + "hashes": [ + "sha256:5e8c00e30c464c99e0b501dc160b13a14af7f27d4dffb529c556e30a159e231d", + "sha256:f277f9ca3e55de669fba45b7393a1449009cff5a37d1af10ebb76c52765269cd" + ], + "version": "==2.1.0" + }, + "pygments": { + "hashes": [ + "sha256:5ffada19f6203563680669ee7f53b64dabbeb100eb51b61996085e99c03b284a", + "sha256:e8218dd399a61674745138520d0d4cf2621d7e032439341bc3f647bff125818d" + ], + "version": "==2.3.1" + }, + "pyrsistent": { + "hashes": [ + "sha256:07f7ae71291af8b0dbad8c2ab630d8223e4a8c4e10fc37badda158c02e753acf" + ], + "version": "==0.14.10" + }, + "pytest": { + "hashes": [ + "sha256:65aeaa77ae87c7fc95de56285282546cfa9c886dc8e5dc78313db1c25e21bc07", + "sha256:6ac6d467d9f053e95aaacd79f831dbecfe730f419c6c7022cb316b365cd9199d" + ], + "index": "pypi", + "version": "==4.2.0" + }, + "python-dateutil": { + "hashes": [ + "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", + "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" + ], + "version": "==2.8.0" + }, + "pyzmq": { + "hashes": [ + "sha256:25a0715c8f69cf72f67cfe5a68a3f3ed391c67c063d2257bec0fe7fc2c7f08f8", + "sha256:2bab63759632c6b9e0d5bf19cc63c3b01df267d660e0abcf230cf0afaa966349", + "sha256:30ab49d99b24bf0908ebe1cdfa421720bfab6f93174e4883075b7ff38cc555ba", + "sha256:32c7ca9fc547a91e3c26fc6080b6982e46e79819e706eb414dd78f635a65d946", + "sha256:41219ae72b3cc86d97557fe5b1ef5d1adc1057292ec597b50050874a970a39cf", + "sha256:4b8c48a9a13cea8f1f16622f9bd46127108af14cd26150461e3eab71e0de3e46", + "sha256:55724997b4a929c0d01b43c95051318e26ddbae23565018e138ae2dc60187e59", + "sha256:65f0a4afae59d4fc0aad54a917ab599162613a761b760ba167d66cc646ac3786", + "sha256:6f88591a8b246f5c285ee6ce5c1bf4f6bd8464b7f090b1333a446b6240a68d40", + "sha256:75022a4c60dcd8765bb9ca32f6de75a0ec83b0d96e0309dc479f4c7b21f26cb7", + "sha256:76ea493bfab18dcb090d825f3662b5612e2def73dffc196d51a5194b0294a81d", + "sha256:7b60c045b80709e4e3c085bab9b691e71761b44c2b42dbb047b8b498e7bc16b3", + "sha256:8e6af2f736734aef8ed6f278f9f552ec7f37b1a6b98e59b887484a840757f67d", + "sha256:9ac2298e486524331e26390eac14e4627effd3f8e001d4266ed9d8f1d2d31cce", + "sha256:9ba650f493a9bc1f24feca1d90fce0e5dd41088a252ac9840131dfbdbf3815ca", + "sha256:a02a4a385e394e46012dc83d2e8fd6523f039bb52997c1c34a2e0dd49ed839c1", + "sha256:a3ceee84114d9f5711fa0f4db9c652af0e4636c89eabc9b7f03a3882569dd1ed", + "sha256:a72b82ac1910f2cf61a49139f4974f994984475f771b0faa730839607eeedddf", + "sha256:ab136ac51027e7c484c53138a0fab4a8a51e80d05162eb7b1585583bcfdbad27", + "sha256:c095b224300bcac61e6c445e27f9046981b1ac20d891b2f1714da89d34c637c8", + "sha256:c5cc52d16c06dc2521340d69adda78a8e1031705924e103c0eb8fc8af861d810", + "sha256:d612e9833a89e8177f8c1dc68d7b4ff98d3186cd331acd616b01bbdab67d3a7b", + "sha256:e828376a23c66c6fe90dcea24b4b72cd774f555a6ee94081670872918df87a19", + "sha256:e9767c7ab2eb552796440168d5c6e23a99ecaade08dda16266d43ad461730192", + "sha256:ebf8b800d42d217e4710d1582b0c8bff20cdcb4faad7c7213e52644034300924" + ], + "version": "==17.1.2" + }, + "qtconsole": { + "hashes": [ + "sha256:1ac4a65e81a27b0838330a6d351c2f8435d4013d98a95373e8a41119b2968390", + "sha256:bc1ba15f50c29ed50f1268ad823bb6543be263c18dd093b80495e9df63b003ac" + ], + "version": "==4.4.3" + }, + "send2trash": { + "hashes": [ + "sha256:60001cc07d707fe247c94f74ca6ac0d3255aabcb930529690897ca2a39db28b2", + "sha256:f1691922577b6fa12821234aeb57599d887c4900b9ca537948d2dac34aea888b" + ], + "version": "==1.5.0" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "version": "==1.12.0" + }, + "terminado": { + "hashes": [ + "sha256:55abf9ade563b8f9be1f34e4233c7b7bde726059947a593322e8a553cc4c067a", + "sha256:65011551baff97f5414c67018e908110693143cfbaeb16831b743fe7cad8b927" + ], + "version": "==0.8.1" + }, + "testpath": { + "hashes": [ + "sha256:46c89ebb683f473ffe2aab0ed9f12581d4d078308a3cb3765d79c6b2317b0109", + "sha256:b694b3d9288dbd81685c5d2e7140b81365d46c29f5db4bc659de5aa6b98780f8" + ], + "version": "==0.4.2" + }, + "toml": { + "hashes": [ + "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", + "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e" + ], + "version": "==0.10.0" + }, + "tornado": { + "hashes": [ + "sha256:00ebd485a52bd7eaa3f35bdf8ab43c109aaa2edc722849b6905c1ffd8c958e82" + ], + "version": "==6.0a1" + }, + "traitlets": { + "hashes": [ + "sha256:9c4bd2d267b7153df9152698efb1050a5d84982d3384a37b2c1f7723ba3e7835", + "sha256:c6cb5e6f57c5a9bdaa40fa71ce7b4af30298fbab9ece9815b5d995ab6217c7d9" + ], + "version": "==4.3.2" + }, + "typed-ast": { + "hashes": [ + "sha256:035a54ede6ce1380599b2ce57844c6554666522e376bd111eb940fbc7c3dad23", + "sha256:037c35f2741ce3a9ac0d55abfcd119133cbd821fffa4461397718287092d9d15", + "sha256:049feae7e9f180b64efacbdc36b3af64a00393a47be22fa9cb6794e68d4e73d3", + "sha256:19228f7940beafc1ba21a6e8e070e0b0bfd1457902a3a81709762b8b9039b88d", + "sha256:2ea681e91e3550a30c2265d2916f40a5f5d89b59469a20f3bad7d07adee0f7a6", + "sha256:3a6b0a78af298d82323660df5497bcea0f0a4a25a0b003afd0ce5af049bd1f60", + "sha256:5385da8f3b801014504df0852bf83524599df890387a3c2b17b7caa3d78b1773", + "sha256:606d8afa07eef77280c2bf84335e24390055b478392e1975f96286d99d0cb424", + "sha256:69245b5b23bbf7fb242c9f8f08493e9ecd7711f063259aefffaeb90595d62287", + "sha256:6f6d839ab09830d59b7fa8fb6917023d8cb5498ee1f1dbd82d37db78eb76bc99", + "sha256:730888475f5ac0e37c1de4bd05eeb799fdb742697867f524dc8a4cd74bcecc23", + "sha256:9819b5162ffc121b9e334923c685b0d0826154e41dfe70b2ede2ce29034c71d8", + "sha256:9e60ef9426efab601dd9aa120e4ff560f4461cf8442e9c0a2b92548d52800699", + "sha256:af5fbdde0690c7da68e841d7fc2632345d570768ea7406a9434446d7b33b0ee1", + "sha256:b64efdbdf3bbb1377562c179f167f3bf301251411eb5ac77dec6b7d32bcda463", + "sha256:bac5f444c118aeb456fac1b0b5d14c6a71ea2a42069b09c176f75e9bd4c186f6", + "sha256:bda9068aafb73859491e13b99b682bd299c1b5fd50644d697533775828a28ee0", + "sha256:d659517ca116e6750101a1326107d3479028c5191f0ecee3c7203c50f5b915b0", + "sha256:eddd3fb1f3e0f82e5915a899285a39ee34ce18fd25d89582bc89fc9fb16cd2c6" + ], + "version": "==1.3.1" + }, + "wcwidth": { + "hashes": [ + "sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e", + "sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c" + ], + "version": "==0.1.7" + }, + "webencodings": { + "hashes": [ + "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", + "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" + ], + "version": "==0.5.1" + }, + "widgetsnbextension": { + "hashes": [ + "sha256:14b2c65f9940c9a7d3b70adbe713dbd38b5ec69724eebaba034d1036cf3d4740", + "sha256:fa618be8435447a017fd1bf2c7ae922d0428056cfc7449f7a8641edf76b48265" + ], + "version": "==3.4.2" + } + } +} diff --git a/{{cookiecutter.project_slug}}/backend/app/alembic/README b/{{cookiecutter.project_slug}}/backend/app/alembic/README new file mode 100755 index 0000000..98e4f9c --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/alembic/README @@ -0,0 +1 @@ +Generic single-database configuration. \ No newline at end of file diff --git a/{{cookiecutter.project_slug}}/backend/app/alembic/env.py b/{{cookiecutter.project_slug}}/backend/app/alembic/env.py new file mode 100755 index 0000000..ae47ee5 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/alembic/env.py @@ -0,0 +1,76 @@ +from __future__ import with_statement +from alembic import context +from sqlalchemy import engine_from_config, pool +from logging.config import fileConfig + +# this is the Alembic Config object, which provides +# access to the values within the .ini file in use. +config = context.config + +# Interpret the config file for Python logging. +# This line sets up loggers basically. +fileConfig(config.config_file_name) + +# add your model's MetaData object here +# for 'autogenerate' support +# from myapp import mymodel +# target_metadata = mymodel.Base.metadata +# target_metadata = None + +from app.db.base import Base # noqa + +target_metadata = Base.metadata + +# other values from the config, defined by the needs of env.py, +# can be acquired: +# my_important_option = config.get_main_option("my_important_option") +# ... etc. + + +def run_migrations_offline(): + """Run migrations in 'offline' mode. + + This configures the context with just a URL + and not an Engine, though an Engine is acceptable + here as well. By skipping the Engine creation + we don't even need a DBAPI to be available. + + Calls to context.execute() here emit the given string to the + script output. + + """ + url = config.get_main_option("sqlalchemy.url") + context.configure( + url=url, target_metadata=target_metadata, literal_binds=True, compare_type=True + ) + + with context.begin_transaction(): + context.run_migrations() + + +def run_migrations_online(): + """Run migrations in 'online' mode. + + In this scenario we need to create an Engine + and associate a connection with the context. + + """ + connectable = engine_from_config( + config.get_section(config.config_ini_section), + prefix="sqlalchemy.", + poolclass=pool.NullPool, + ) + + with connectable.connect() as connection: + context.configure( + connection=connection, target_metadata=target_metadata, compare_type=True + ) + + with context.begin_transaction(): + context.run_migrations() + + +if context.is_offline_mode(): + run_migrations_offline() +else: + run_migrations_online() diff --git a/{{cookiecutter.project_slug}}/backend/app/alembic/script.py.mako b/{{cookiecutter.project_slug}}/backend/app/alembic/script.py.mako new file mode 100755 index 0000000..2c01563 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/alembic/script.py.mako @@ -0,0 +1,24 @@ +"""${message} + +Revision ID: ${up_revision} +Revises: ${down_revision | comma,n} +Create Date: ${create_date} + +""" +from alembic import op +import sqlalchemy as sa +${imports if imports else ""} + +# revision identifiers, used by Alembic. +revision = ${repr(up_revision)} +down_revision = ${repr(down_revision)} +branch_labels = ${repr(branch_labels)} +depends_on = ${repr(depends_on)} + + +def upgrade(): + ${upgrades if upgrades else "pass"} + + +def downgrade(): + ${downgrades if downgrades else "pass"} diff --git a/{{cookiecutter.project_slug}}/backend/app/alembic/versions/.keep b/{{cookiecutter.project_slug}}/backend/app/alembic/versions/.keep new file mode 100755 index 0000000..e69de29 diff --git a/{{cookiecutter.project_slug}}/backend/app/app/__init__.py b/{{cookiecutter.project_slug}}/backend/app/app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/{{cookiecutter.project_slug}}/backend/app/app/api/__init__.py b/{{cookiecutter.project_slug}}/backend/app/app/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/__init__.py b/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/api.py b/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/api.py new file mode 100644 index 0000000..5ec46a5 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/api.py @@ -0,0 +1,12 @@ +from fastapi import APIRouter + +from app.api.api_v1.endpoints.role import router as roles_router +from app.api.api_v1.endpoints.token import router as token_router +from app.api.api_v1.endpoints.user import router as user_router +from app.api.api_v1.endpoints.utils import router as utils_router + +api_router = APIRouter() +api_router.include_router(roles_router) +api_router.include_router(token_router) +api_router.include_router(user_router) +api_router.include_router(utils_router) diff --git a/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/__init__.py b/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/role.py b/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/role.py new file mode 100644 index 0000000..18118b1 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/role.py @@ -0,0 +1,25 @@ +from fastapi import APIRouter, Depends +from starlette.exceptions import HTTPException + +from app.core.jwt import get_current_user +from app.crud.user import check_if_user_is_active, check_if_user_is_superuser +from app.crud.utils import ensure_enums_to_strs +from app.models.role import RoleEnum, Roles +from app.models.user import UserInDB + +router = APIRouter() + + +@router.get("/roles/", response_model=Roles) +def route_roles_get(current_user: UserInDB = Depends(get_current_user)): + """ + Retrieve roles + """ + if not check_if_user_is_active(current_user): + raise HTTPException(status_code=400, detail="Inactive user") + elif not (check_if_user_is_superuser(current_user)): + raise HTTPException( + status_code=400, detail="The current user does not have enogh privileges" + ) + roles = ensure_enums_to_strs(RoleEnum) + return {"roles": roles} diff --git a/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/token.py b/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/token.py new file mode 100644 index 0000000..26a1725 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/token.py @@ -0,0 +1,96 @@ +from datetime import timedelta + +from fastapi import APIRouter, Depends +from fastapi.security import OAuth2PasswordRequestForm +from starlette.exceptions import HTTPException + +from app.core import config +from app.core.jwt import create_access_token, get_current_user +from app.crud.user import ( + authenticate_user, + check_if_user_is_active, + check_if_user_is_superuser, + get_user, + update_user, +) +from app.db.database import get_default_bucket +from app.models.msg import Msg +from app.models.token import Token +from app.models.user import User, UserInDB, UserInUpdate +from app.utils import ( + generate_password_reset_token, + send_reset_password_email, + verify_password_reset_token, +) + +router = APIRouter() + + +@router.post("/login/access-token", response_model=Token, tags=["login"]) +def route_login_access_token(form_data: OAuth2PasswordRequestForm = Depends()): + """ + OAuth2 compatible token login, get an access token for future requests + """ + bucket = get_default_bucket() + user = authenticate_user(bucket, form_data.username, form_data.password) + if not user: + raise HTTPException(status_code=400, detail="Incorrect email or password") + elif not check_if_user_is_active(user): + raise HTTPException(status_code=400, detail="Inactive user") + access_token_expires = timedelta(minutes=config.ACCESS_TOKEN_EXPIRE_MINUTES) + return { + "access_token": create_access_token( + data={"username": form_data.username}, expires_delta=access_token_expires + ), + "token_type": "bearer", + } + + +@router.post("/login/test-token", tags=["login"], response_model=User) +def route_test_token(current_user: UserInDB = Depends(get_current_user)): + """ + Test access token + """ + return current_user + + +@router.post("/password-recovery/{username}", tags=["login"], response_model=Msg) +def route_recover_password(username: str): + """ + Password Recovery + """ + bucket = get_default_bucket() + user = get_user(bucket, username) + + if not user: + raise HTTPException( + status_code=404, + detail="The user with this username does not exist in the system.", + ) + password_reset_token = generate_password_reset_token(username) + send_reset_password_email( + email_to=user.email, username=username, token=password_reset_token + ) + return {"msg": "Password recovery email sent"} + + +@router.post("/reset-password/", tags=["login"], response_model=Msg) +def route_reset_password(token: str, new_password: str): + """ + Reset password + """ + username = verify_password_reset_token(token) + if not username: + raise HTTPException(status_code=400, detail="Invalid token") + bucket = get_default_bucket() + user = get_user(bucket, username) + if not user: + raise HTTPException( + status_code=404, + detail="The user with this username does not exist in the system.", + ) + elif not check_if_user_is_active(user): + raise HTTPException(status_code=400, detail="Inactive user") + user_in = UserInUpdate(name=username, password=new_password) + user = update_user(bucket, user_in) + return {"msg": "Password updated successfully"} diff --git a/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/user.py b/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/user.py new file mode 100644 index 0000000..2af90ba --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/user.py @@ -0,0 +1,205 @@ +from typing import List + +from fastapi import APIRouter, Body, Depends +from pydantic.types import EmailStr +from starlette.exceptions import HTTPException + +from app.core import config +from app.core.jwt import get_current_user +from app.crud.user import ( + check_if_user_is_active, + check_if_user_is_superuser, + get_user, + get_users, + search_users, + update_user, + upsert_user, +) +from app.db.database import get_default_bucket +from app.models.user import User, UserInCreate, UserInDB, UserInUpdate +from app.utils import send_new_account_email + +router = APIRouter() + + +@router.get("/users/", tags=["users"], response_model=List[User]) +def route_users_get( + skip: int = 0, limit: int = 100, current_user: UserInDB = Depends(get_current_user) +): + """ + Retrieve users + """ + if not check_if_user_is_active(current_user): + raise HTTPException(status_code=400, detail="Inactive user") + elif not check_if_user_is_superuser(current_user): + raise HTTPException( + status_code=400, detail="The user doesn't have enough privileges" + ) + bucket = get_default_bucket() + users = get_users(bucket, skip=skip, limit=limit) + return users + + +@router.get("/users/search/", tags=["users"], response_model=List[User]) +def route_search_users( + q: str, + skip: int = 0, + limit: int = 100, + current_user: UserInDB = Depends(get_current_user), +): + """ + Search users, use Bleve Query String syntax: http://blevesearch.com/docs/Query-String-Query/ + + For typeahead sufix with `*`. For example, a query with: `email:johnd*` will match users with + email `johndoe@example.com`, `johndid@example.net`, etc. + """ + if not check_if_user_is_active(current_user): + raise HTTPException(status_code=400, detail="Inactive user") + elif not check_if_user_is_superuser(current_user): + raise HTTPException( + status_code=400, detail="The user doesn't have enough privileges" + ) + bucket = get_default_bucket() + users = search_users(bucket=bucket, query_string=q, skip=skip, limit=limit) + return users + + +@router.post("/users/", tags=["users"], response_model=User) +def route_users_post( + *, user_in: UserInCreate, current_user: UserInDB = Depends(get_current_user) +): + """ + Create new user + """ + if not check_if_user_is_active(current_user): + raise HTTPException(status_code=400, detail="Inactive user") + elif not check_if_user_is_superuser(current_user): + raise HTTPException( + status_code=400, detail="The user doesn't have enough privileges" + ) + bucket = get_default_bucket() + user = get_user(bucket, user_in.username) + if user: + raise HTTPException( + status_code=400, + detail="The user with this username already exists in the system.", + ) + user = upsert_user(bucket, user_in, persist_to=1) + if config.EMAILS_ENABLED and user_in.email: + send_new_account_email( + email_to=user_in.email, username=user_in.username, password=user_in.password + ) + return user + + +@router.put("/users/me", tags=["users"], response_model=User) +def route_users_me_put( + *, + password: str = None, + full_name: str = None, + email: EmailStr = None, + current_user: UserInDB = Depends(get_current_user), +): + """ + Update own user + """ + if not check_if_user_is_active(current_user): + raise HTTPException(status_code=400, detail="Inactive user") + user_in = UserInUpdate(**current_user.dict()) + if password is not None: + user_in.password = password + if full_name is not None: + user_in.full_name = full_name + if email is not None: + user_in.email = email + bucket = get_default_bucket() + user = update_user(bucket, user_in) + return user + + +@router.get("/users/me", tags=["users"], response_model=User) +def route_users_me_get(current_user: UserInDB = Depends(get_current_user)): + """ + Get current user + """ + if not check_if_user_is_active(current_user): + raise HTTPException(status_code=400, detail="Inactive user") + return current_user + + +@router.post("/users/open", tags=["users"], response_model=User) +def route_users_post_open( + *, + username: str = Body(...), + password: str = Body(...), + email: EmailStr = Body(None), + full_name: str = Body(None), +): + """ + Create new user without the need to be logged in + """ + if not config.USERS_OPEN_REGISTRATION: + raise HTTPException( + status_code=403, + detail="Open user resgistration is forbidden on this server", + ) + bucket = get_default_bucket() + user = get_user(bucket, username) + if user: + raise HTTPException( + status_code=400, + detail="The user with this username already exists in the system", + ) + user_in = UserInCreate( + username=username, password=password, email=email, full_name=full_name + ) + user = upsert_user(bucket, user_in, persist_to=1) + return user + + +@router.get("/users/{username}", tags=["users"], response_model=User) +def route_users_id_get( + username: str, current_user: UserInDB = Depends(get_current_user) +): + """ + Get a specific user by username (email) + """ + if not check_if_user_is_active(current_user): + raise HTTPException(status_code=400, detail="Inactive user") + bucket = get_default_bucket() + user = get_user(bucket, username) + if user == current_user: + return user + if not check_if_user_is_superuser(current_user): + raise HTTPException( + status_code=400, detail="The user doesn't have enough privileges" + ) + return user + + +@router.put("/users/{username}", tags=["users"], response_model=User) +def route_users_put( + *, + username: str, + user_in: UserInUpdate, + current_user: UserInDB = Depends(get_current_user), +): + """ + Update a user + """ + if not check_if_user_is_active(current_user): + raise HTTPException(status_code=400, detail="Inactive user") + elif not check_if_user_is_superuser(current_user): + raise HTTPException( + status_code=400, detail="The user doesn't have enough privileges" + ) + bucket = get_default_bucket() + user = get_user(bucket, username) + + if not user: + raise HTTPException( + status_code=404, + detail="The user with this username does not exist in the system", + ) + user = update_user(bucket, user_in) + return user diff --git a/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/utils.py b/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/utils.py new file mode 100644 index 0000000..34a869b --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/api/api_v1/endpoints/utils.py @@ -0,0 +1,36 @@ +from fastapi import APIRouter, Depends +from pydantic.types import EmailStr +from starlette.exceptions import HTTPException + +from app.core.celery_app import celery_app +from app.core.jwt import get_current_user +from app.crud.user import check_if_user_is_superuser +from app.models.msg import Msg +from app.models.user import UserInDB +from app.utils import send_test_email + +router = APIRouter() + + +@router.post("/test-celery/", tags=["utils"], response_model=Msg, status_code=201) +def route_test_celery(msg: Msg, current_user: UserInDB = Depends(get_current_user)): + """ + Test Celery worker + """ + if not check_if_user_is_superuser(current_user): + raise HTTPException(status_code=400, detail="Not a superuser") + celery_app.send_task("app.worker.test_celery", args=[msg.msg]) + return {"msg": "Word received"} + + +@router.post("/test-email/", tags=["utils"], response_model=Msg, status_code=201) +def route_test_email( + email_to: EmailStr, current_user: UserInDB = Depends(get_current_user) +): + """ + Test emails + """ + if not check_if_user_is_superuser(current_user): + raise HTTPException(status_code=400, detail="Not a superuser") + send_test_email(email_to=email_to) + return {"msg": "Test email sent"} diff --git a/{{cookiecutter.project_slug}}/backend/app/app/backend_pre_start.py b/{{cookiecutter.project_slug}}/backend/app/app/backend_pre_start.py new file mode 100644 index 0000000..932ed41 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/backend_pre_start.py @@ -0,0 +1,32 @@ +import logging + +from tenacity import after_log, before_log, retry, stop_after_attempt, wait_fixed + +from app.db.external_session import db_session + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +max_tries = 60 * 5 # 5 minutes +wait_seconds = 1 + + +@retry( + stop=stop_after_attempt(max_tries), + wait=wait_fixed(wait_seconds), + before=before_log(logger, logging.INFO), + after=after_log(logger, logging.WARN), +) +def init(): + # Try to create session to check if DB is awake + db_session.execute("SELECT 1") + + +def main(): + logger.info("Initializing service") + init() + logger.info("Service finished initializing") + + +if __name__ == "__main__": + main() diff --git a/{{cookiecutter.project_slug}}/backend/app/app/celeryworker_pre_start.py b/{{cookiecutter.project_slug}}/backend/app/app/celeryworker_pre_start.py new file mode 100644 index 0000000..932ed41 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/celeryworker_pre_start.py @@ -0,0 +1,32 @@ +import logging + +from tenacity import after_log, before_log, retry, stop_after_attempt, wait_fixed + +from app.db.external_session import db_session + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +max_tries = 60 * 5 # 5 minutes +wait_seconds = 1 + + +@retry( + stop=stop_after_attempt(max_tries), + wait=wait_fixed(wait_seconds), + before=before_log(logger, logging.INFO), + after=after_log(logger, logging.WARN), +) +def init(): + # Try to create session to check if DB is awake + db_session.execute("SELECT 1") + + +def main(): + logger.info("Initializing service") + init() + logger.info("Service finished initializing") + + +if __name__ == "__main__": + main() diff --git a/{{cookiecutter.project_slug}}/backend/app/app/core/__init__.py b/{{cookiecutter.project_slug}}/backend/app/app/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/{{cookiecutter.project_slug}}/backend/app/app/core/celery_app.py b/{{cookiecutter.project_slug}}/backend/app/app/core/celery_app.py new file mode 100644 index 0000000..0477d14 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/core/celery_app.py @@ -0,0 +1,5 @@ +from celery import Celery + +celery_app = Celery("worker", broker="amqp://guest@queue//") + +celery_app.conf.task_routes = {"app.worker.test_celery": "main-queue"} diff --git a/{{cookiecutter.project_slug}}/backend/app/app/core/config.py b/{{cookiecutter.project_slug}}/backend/app/app/core/config.py new file mode 100644 index 0000000..0334ba2 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/core/config.py @@ -0,0 +1,78 @@ +import os + + +def getenv_boolean(var_name, default_value=False): + result = default_value + env_value = os.getenv(var_name) + if env_value is not None: + result = env_value.upper() in ("TRUE", "1") + return result + + +API_V1_STR = "/api/v1" + +SECRET_KEY = os.getenvb(b"SECRET_KEY") +if not SECRET_KEY: + SECRET_KEY = os.urandom(32) + +ACCESS_TOKEN_EXPIRE_MINUTES = 60 * 24 * 8 # 60 minutes * 24 hours * 8 days = 8 days + +SERVER_NAME = os.getenv("SERVER_NAME") +SERVER_HOST = os.getenv("SERVER_HOST") +BACKEND_CORS_ORIGINS = os.getenv( + "BACKEND_CORS_ORIGINS" +) # a string of origins separated by commas, e.g: "http://localhost, http://localhost:4200, http://localhost:3000, http://localhost:8080, http://dev.couchbase-project.com, https://stag.couchbase-project.com, https://couchbase-project.com, http://local.dockertoolbox.tiangolo.com" +PROJECT_NAME = os.getenv("PROJECT_NAME") +SENTRY_DSN = os.getenv("SENTRY_DSN") + +# Couchbase server settings +COUCHBASE_MEMORY_QUOTA_MB = os.getenv("COUCHBASE_MEMORY_QUOTA_MB", "256") +COUCHBASE_INDEX_MEMORY_QUOTA_MB = os.getenv("COUCHBASE_INDEX_MEMORY_QUOTA_MB" "256") +COUCHBASE_FTS_MEMORY_QUOTA_MB = os.getenv("COUCHBASE_FTS_MEMORY_QUOTA_MB", "256") +COUCHBASE_HOST = os.getenv("COUCHBASE_HOST", "couchbase") +COUCHBASE_PORT = os.getenv("COUCHBASE_PORT", "8091") +COUCHBASE_FULL_TEXT_PORT = os.getenv("COUCHBASE_FULL_TEXT_PORT", "8094") +COUCHBASE_ENTERPRISE = getenv_boolean("COUCHBASE_ENTERPRISE") +COUCHBASE_USER = os.getenv("COUCHBASE_USER", "Administrator") +COUCHBASE_PASSWORD = os.getenv("COUCHBASE_PASSWORD", "password") +COUCHBASE_BUCKET_NAME = os.getenv("COUCHBASE_BUCKET_NAME", "app") + +COUCHBASE_SYNC_GATEWAY_HOST = os.getenv("COUCHBASE_SYNC_GATEWAY_HOST", "sync-gateway") +COUCHBASE_SYNC_GATEWAY_PORT = os.getenv("COUCHBASE_SYNC_GATEWAY_PORT", "4985") +COUCHBASE_SYNC_GATEWAY_USER = os.getenv("COUCHBASE_SYNC_GATEWAY_USER") +COUCHBASE_SYNC_GATEWAY_PASSWORD = os.getenv("COUCHBASE_SYNC_GATEWAY_PASSWORD") +COUCHBASE_SYNC_GATEWAY_DATABASE = os.getenv("COUCHBASE_SYNC_GATEWAY_DATABASE") + +# Couchbase query timeouts +COUCHBASE_DURABILITY_TIMEOUT_SECS = 60.0 +COUCHBASE_OPERATION_TIMEOUT_SECS = 30.0 +COUCHBASE_N1QL_TIMEOUT_SECS = 300.0 + + +# Couchbase Sync Gateway settings +COUCHBASE_CORS_ORIGINS = os.getenv("COUCHBASE_CORS_ORIGINS") +# a string of origins separated by commas, e.g: "http://localhost:5984, http://localhost, http://localhost:4200, http://localhost:3000, http://localhost:8080, http://dev.couchbase-project.com, https://stag.couchbase-project.com, https://db.stag.couchbase-project.com, https://couchbase-project.com, https://db.couchbase-project.com, http://local.dockertoolbox.tiangolo.com, http://local.dockertoolbox.tiangolo.com:5984" +COUCHBASE_AUTH_TIMEOUT = ACCESS_TOKEN_EXPIRE_MINUTES * 60 + +COUCHBASE_FULL_TEXT_INDEX_DEFINITIONS_DIR = "/app/app/search_index_definitions/" + +SMTP_TLS = getenv_boolean("SMTP_TLS", True) +SMTP_PORT = None +_SMTP_PORT = os.getenv("SMTP_PORT") +if _SMTP_PORT is not None: + SMTP_PORT = int(_SMTP_PORT) +SMTP_HOST = os.getenv("SMTP_HOST") +SMTP_USER = os.getenv("SMTP_USER") +SMTP_PASSWORD = os.getenv("SMTP_PASSWORD") +EMAILS_FROM_EMAIL = os.getenv("EMAILS_FROM_EMAIL") +EMAILS_FROM_NAME = PROJECT_NAME +EMAIL_RESET_TOKEN_EXPIRE_HOURS = 48 +EMAIL_TEMPLATES_DIR = "/app/app/email-templates/build" +EMAILS_ENABLED = SMTP_HOST and SMTP_PORT and EMAILS_FROM_EMAIL + +ROLE_SUPERUSER = "superuser" + +FIRST_SUPERUSER = os.getenv("FIRST_SUPERUSER") +FIRST_SUPERUSER_PASSWORD = os.getenv("FIRST_SUPERUSER_PASSWORD") + +USERS_OPEN_REGISTRATION = getenv_boolean("USERS_OPEN_REGISTRATION") diff --git a/{{cookiecutter.project_slug}}/backend/app/app/core/jwt.py b/{{cookiecutter.project_slug}}/backend/app/app/core/jwt.py new file mode 100644 index 0000000..0acd756 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/core/jwt.py @@ -0,0 +1,44 @@ +from datetime import datetime, timedelta + +import jwt +from fastapi import Security +from fastapi.security import OAuth2PasswordBearer +from jwt import PyJWTError +from starlette.exceptions import HTTPException +from starlette.status import HTTP_403_FORBIDDEN + +from app.core.config import SECRET_KEY +from app.crud.user import get_user +from app.db.database import get_default_bucket +from app.models.token import TokenPayload + +ALGORITHM = "HS256" +access_token_jwt_subject = "access" + +reusable_oauth2 = OAuth2PasswordBearer(tokenUrl="/api/v1/login/access-token") + + +def get_current_user(token: str = Security(reusable_oauth2)): + try: + payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) + token_data = TokenPayload(**payload) + except PyJWTError: + raise HTTPException( + status_code=HTTP_403_FORBIDDEN, detail="Could not validate credentials" + ) + bucket = get_default_bucket() + user = get_user(bucket, username=token_data.username) + if not user: + raise HTTPException(status_code=404, detail="User not found") + return user + + +def create_access_token(*, data: dict, expires_delta: timedelta = None): + to_encode = data.copy() + if expires_delta: + expire = datetime.utcnow() + expires_delta + else: + expire = datetime.utcnow() + timedelta(minutes=15) + to_encode.update({"exp": expire, "sub": access_token_jwt_subject}) + encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) + return encoded_jwt diff --git a/{{cookiecutter.project_slug}}/backend/app/app/core/security.py b/{{cookiecutter.project_slug}}/backend/app/app/core/security.py new file mode 100644 index 0000000..df7b656 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/core/security.py @@ -0,0 +1,11 @@ +from passlib.context import CryptContext + +pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") + + +def verify_password(plain_password, hashed_password): + return pwd_context.verify(plain_password, hashed_password) + + +def get_password_hash(password): + return pwd_context.hash(password) diff --git a/{{cookiecutter.project_slug}}/backend/app/app/crud/__init__.py b/{{cookiecutter.project_slug}}/backend/app/app/crud/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/{{cookiecutter.project_slug}}/backend/app/app/crud/user.py b/{{cookiecutter.project_slug}}/backend/app/app/crud/user.py new file mode 100644 index 0000000..531a0bb --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/crud/user.py @@ -0,0 +1,91 @@ +from app.core.security import get_password_hash +from app.models.role import Role +from app.models.user import User + + +def get_user(username, db_session): + return db_session.query(User).filter(User.id == username).first() + + +def check_if_user_is_active(user): + return user.is_active + + +def check_if_user_is_superuser(user): + return user.is_superuser + + +def check_if_username_is_active(username, db_session): + user = get_user(username, db_session) + return check_if_user_is_active(user) + + +def get_role_by_name(name, db_session): + role = db_session.query(Role).filter(Role.name == name).first() + return role + + +def get_role_by_id(role_id, db_session): + role = db_session.query(Role).filter(Role.id == role_id).first() + return role + + +def create_role(name, db_session): + role = Role(name=name) + db_session.add(role) + db_session.commit() + return role + + +def get_roles(db_session): + return db_session.query(Role).all() + + +def get_user_roles(user): + return user.roles + + +def get_user_by_username(username, db_session) -> User: + user = db_session.query(User).filter(User.email == username).first() # type: User + return user + + +def get_user_by_id(user_id, db_session): + user = db_session.query(User).filter(User.id == user_id).first() # type: User + return user + + +def get_user_hashed_password(user): + return user.password + + +def get_user_id(user): + return user.id + + +def get_users(db_session): + return db_session.query(User).all() + + +def create_user( + db_session, username, password, first_name=None, last_name=None, is_superuser=False +): + user = User( + email=username, + password=get_password_hash(password), + first_name=first_name, + last_name=last_name, + is_superuser=is_superuser, + ) + db_session.add(user) + db_session.commit() + db_session.refresh(user) + return user + + +def assign_role_to_user(role: Role, user: User, db_session): + user.roles.append(role) + db_session.add(user) + db_session.commit() + db_session.refresh(user) + return user diff --git a/{{cookiecutter.project_slug}}/backend/app/app/crud/utils.py b/{{cookiecutter.project_slug}}/backend/app/app/crud/utils.py new file mode 100644 index 0000000..fde3c59 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/crud/utils.py @@ -0,0 +1,214 @@ +import uuid +from enum import Enum +from typing import List, Sequence, Type, Union + +from pydantic import BaseModel +from pydantic.fields import Field, Shape + +from app.core.config import COUCHBASE_BUCKET_NAME +from couchbase.bucket import Bucket +from couchbase.fulltext import MatchAllQuery, QueryStringQuery +from couchbase.n1ql import CONSISTENCY_REQUEST, N1QLQuery + + +def generate_new_id(): + return str(uuid.uuid4()) + + +def ensure_enums_to_strs(items: Union[Sequence[Union[Enum, str]], Type[Enum]]): + str_items = [] + for item in items: + if isinstance(item, Enum): + str_items.append(str(item.value)) + else: + str_items.append(str(item)) + return str_items + + +def get_all_documents_by_type(bucket: Bucket, *, doc_type: str, skip=0, limit=100): + query_str = f"SELECT *, META().id as id FROM {COUCHBASE_BUCKET_NAME} WHERE type = $type LIMIT $limit OFFSET $skip;" + q = N1QLQuery( + query_str, bucket=COUCHBASE_BUCKET_NAME, type=doc_type, limit=limit, skip=skip + ) + q.consistency = CONSISTENCY_REQUEST + result = bucket.n1ql_query(q) + return result + + +def get_documents_by_keys( + bucket: Bucket, *, keys: List[str], doc_model=Type[BaseModel] +): + results = bucket.get_multi(keys, quiet=True) + docs = [] + for result in results.values(): + doc = doc_model(**result.value) + docs.append(doc) + return docs + + +def results_to_model(results_from_couchbase: list, *, doc_model: Type[BaseModel]): + items = [] + for doc in results_from_couchbase: + data = doc[COUCHBASE_BUCKET_NAME] + doc = doc_model(**data) + items.append(doc) + return items + + +def search_results_to_model( + results_from_couchbase: list, *, doc_model: Type[BaseModel] +): + items = [] + for doc in results_from_couchbase: + data = doc.get("fields") + if not data: + continue + data_nones = {} + for key, value in data.items(): + field: Field = doc_model.__fields__[key] + if not value: + value = None + elif field.shape in {Shape.LIST, Shape.SET, Shape.TUPLE} and not isinstance( + value, list + ): + value = [value] + data_nones[key] = value + doc = doc_model(**data_nones) + items.append(doc) + return items + + +def get_docs( + bucket: Bucket, *, doc_type: str, doc_model=Type[BaseModel], skip=0, limit=100 +): + doc_results = get_all_documents_by_type( + bucket, doc_type=doc_type, skip=skip, limit=limit + ) + return results_to_model(doc_results, doc_model=doc_model) + + +def get_doc(bucket: Bucket, *, doc_id: str, doc_model: Type[BaseModel]): + result = bucket.get(doc_id, quiet=True) + if not result.value: + return None + model = doc_model(**result.value) + return model + + +def search_docs_get_doc_ids( + bucket: Bucket, + *, + query_string: str, + index_name: str, + skip: int = 0, + limit: int = 100, +): + query = QueryStringQuery(query_string) + hits = bucket.search(index_name, query, skip=skip, limit=limit) + doc_ids = [] + for hit in hits: + doc_ids.append(hit["id"]) + return doc_ids + + +def search_get_results( + bucket: Bucket, + *, + query_string: str, + index_name: str, + skip: int = 0, + limit: int = 100, +): + if query_string: + query = QueryStringQuery(query_string) + else: + query = MatchAllQuery() + hits = bucket.search(index_name, query, fields=["*"], skip=skip, limit=limit) + docs = [] + for hit in hits: + docs.append(hit) + return docs + + +def search_get_results_by_type( + bucket: Bucket, + *, + query_string: str, + index_name: str, + doc_type: str, + skip: int = 0, + limit: int = 100, +): + type_filter = f"type:{doc_type}" + if not query_string: + query_string = type_filter + if query_string and type_filter not in query_string: + query_string += f" {type_filter}" + query = QueryStringQuery(query_string) + hits = bucket.search(index_name, query, fields=["*"], skip=skip, limit=limit) + docs = [] + for hit in hits: + docs.append(hit) + return docs + + +def search_docs( + bucket: Bucket, + *, + query_string: str, + index_name: str, + doc_model: Type[BaseModel], + skip=0, + limit=100, +): + keys = search_docs_get_doc_ids( + bucket=bucket, + query_string=query_string, + index_name=index_name, + skip=skip, + limit=limit, + ) + if not keys: + return [] + doc_results = get_documents_by_keys(bucket=bucket, keys=keys, doc_model=doc_model) + return doc_results + + +def search_results( + bucket: Bucket, + *, + query_string: str, + index_name: str, + doc_model: Type[BaseModel], + skip=0, + limit=100, +): + doc_results = search_get_results( + bucket=bucket, + query_string=query_string, + index_name=index_name, + skip=skip, + limit=limit, + ) + return search_results_to_model(doc_results, doc_model=doc_model) + + +def search_results_by_type( + bucket: Bucket, + *, + query_string: str, + index_name: str, + doc_type: str, + doc_model: Type[BaseModel], + skip=0, + limit=100, +): + doc_results = search_get_results_by_type( + bucket=bucket, + query_string=query_string, + index_name=index_name, + doc_type=doc_type, + skip=skip, + limit=limit, + ) + return search_results_to_model(doc_results, doc_model=doc_model) diff --git a/{{cookiecutter.project_slug}}/backend/app/app/db/__init__.py b/{{cookiecutter.project_slug}}/backend/app/app/db/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/{{cookiecutter.project_slug}}/backend/app/app/db/base.py b/{{cookiecutter.project_slug}}/backend/app/app/db/base.py new file mode 100644 index 0000000..62920c7 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/db/base.py @@ -0,0 +1,5 @@ +# Import all the models, so that Base has them before being +# imported by Alembic +from app.db.base_class import Base # noqa +from app.models.role import Role # noqa +from app.models.user import User # noqa diff --git a/{{cookiecutter.project_slug}}/backend/app/app/db/base_class.py b/{{cookiecutter.project_slug}}/backend/app/app/db/base_class.py new file mode 100644 index 0000000..2228a37 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/db/base_class.py @@ -0,0 +1,11 @@ +from sqlalchemy.ext.declarative import declarative_base, declared_attr + + +class CustomBase(object): + # Generate __tablename__ automatically + @declared_attr + def __tablename__(cls): + return cls.__name__.lower() + + +Base = declarative_base(cls=CustomBase) diff --git a/{{cookiecutter.project_slug}}/backend/app/app/db/external_session.py b/{{cookiecutter.project_slug}}/backend/app/app/db/external_session.py new file mode 100644 index 0000000..82a1a4b --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/db/external_session.py @@ -0,0 +1,8 @@ +from app.core import config +from sqlalchemy import create_engine +from sqlalchemy.orm import scoped_session, sessionmaker + +engine = create_engine(config.SQLALCHEMY_DATABASE_URI, convert_unicode=True) +db_session = scoped_session( + sessionmaker(autocommit=False, autoflush=False, bind=engine) +) diff --git a/{{cookiecutter.project_slug}}/backend/app/app/db/full_text_search_utils.py b/{{cookiecutter.project_slug}}/backend/app/app/db/full_text_search_utils.py new file mode 100644 index 0000000..f8d45fa --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/db/full_text_search_utils.py @@ -0,0 +1,106 @@ +import json +from pathlib import Path, PurePath +from typing import Any, Dict + +import requests +from requests.auth import HTTPBasicAuth + +from app.core.config import ( + COUCHBASE_FULL_TEXT_INDEX_DEFINITIONS_DIR, + COUCHBASE_PASSWORD, + COUCHBASE_USER, +) + + +def get_index( + index_name: str, + *, + username: str = COUCHBASE_USER, + password: str = COUCHBASE_PASSWORD, + host="couchbase", + port="8094", +): + full_text_url = f"http://{host}:{port}" + index_url = f"{full_text_url}/api/index/{index_name}" + auth = HTTPBasicAuth(username, password) + response = requests.get(index_url, auth=auth) + if response.status_code == 400: + content = response.json() + error = content.get("error") + if error == "rest_auth: preparePerms, err: index not found": + return None + raise ValueError(error) + elif response.status_code == 200: + content = response.json() + assert ( + content.get("status") == "ok" + ), "Expected a status OK communicating with Full Text Search" + index_def = content.get("indexDef") + return index_def + raise ValueError(response.text) + + +def create_index( + index_definition: Dict[str, Any], + *, + reset_uuids=True, + username: str = COUCHBASE_USER, + password: str = COUCHBASE_PASSWORD, + host="couchbase", + port="8094", +): + index_name = index_definition.get("name") + assert index_name, "An index name is required as key in an index definition" + if reset_uuids: + index_definition.update({"uuid": "", "sourceUUID": ""}) + full_text_url = f"http://{host}:{port}" + index_url = f"{full_text_url}/api/index/{index_name}" + auth = HTTPBasicAuth(username, password) + response = requests.put(index_url, auth=auth, json=index_definition) + content = response.json() + if response.status_code == 400: + error = content.get("error") + if ( + "cannot create index because an index with the same name already exists:" + in error + ): + raise ValueError(error) + else: + raise ValueError(error) + elif response.status_code == 200: + assert ( + content.get("status") == "ok" + ), "Expected a status OK communicating with Full Text Search" + return True + raise ValueError(response.text) + + +def ensure_create_full_text_indexes( + index_dir=COUCHBASE_FULL_TEXT_INDEX_DEFINITIONS_DIR, + username: str = COUCHBASE_USER, + password: str = COUCHBASE_PASSWORD, + host="couchbase", + port="8094", +): + file_path: PurePath + for file_path in Path(index_dir).iterdir(): + if file_path.name.endswith(".json"): + with open(file_path) as f: + index_definition = json.load(f) + name = index_definition.get("name") + assert name, "A full text search index definition must have a name field" + current_index = get_index( + index_name=name, + username=username, + password=password, + host=host, + port=port, + ) + if not current_index: + assert create_index( + index_definition=index_definition, + username=username, + password=password, + host=host, + port=port, + ), "Full Text Search index could not be created" diff --git a/{{cookiecutter.project_slug}}/backend/app/app/db/init_db.py b/{{cookiecutter.project_slug}}/backend/app/app/db/init_db.py new file mode 100644 index 0000000..1a80545 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/db/init_db.py @@ -0,0 +1,29 @@ +from app.core import config +from app.db.utils import ( + assign_role_to_user, + create_role, + create_user, + get_role_by_name, + get_user_by_username, +) + + +def init_db(db_session): + # Tables should be created with Alembic migrations + # But if you don't want to use migrations, create + # the tables uncommenting the next line + # Base.metadata.create_all(bind=engine) + + role = get_role_by_name("default", db_session) + if not role: + role = create_role("default", db_session) + + user = get_user_by_username(config.FIRST_SUPERUSER, db_session) + if not user: + user = create_user( + db_session, + config.FIRST_SUPERUSER, + config.FIRST_SUPERUSER_PASSWORD, + is_superuser=True, + ) + assign_role_to_user(role, user, db_session) diff --git a/{{cookiecutter.project_slug}}/backend/app/app/db_models/__init__.py b/{{cookiecutter.project_slug}}/backend/app/app/db_models/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/{{cookiecutter.project_slug}}/backend/app/app/db_models/base_relations.py b/{{cookiecutter.project_slug}}/backend/app/app/db_models/base_relations.py new file mode 100755 index 0000000..9b7309d --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/db_models/base_relations.py @@ -0,0 +1,11 @@ +# Import installed packages +# Import app code +from app.db.base_class import Base +from sqlalchemy import Column, ForeignKey, Integer, Table + +users_roles = Table( + "users_roles", + Base.metadata, + Column("user_id", Integer, ForeignKey("user.id")), + Column("role_id", Integer, ForeignKey("role.id")), +) diff --git a/{{cookiecutter.project_slug}}/backend/app/app/db_models/role.py b/{{cookiecutter.project_slug}}/backend/app/app/db_models/role.py new file mode 100755 index 0000000..b0e18d8 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/db_models/role.py @@ -0,0 +1,19 @@ +# Import standard library packages +from datetime import datetime + +# Import app code +from app.db.base_class import Base +from app.models.base_relations import users_roles + +# Import installed packages +from sqlalchemy import Column, DateTime, Integer, String +from sqlalchemy.orm import relationship + + +class Role(Base): + # Own properties + id = Column(Integer, primary_key=True, index=True) + created_at = Column(DateTime, default=datetime.utcnow(), index=True) + name = Column(String, index=True) + # Relationships + users = relationship("User", secondary=users_roles, back_populates="roles") diff --git a/{{cookiecutter.project_slug}}/backend/app/app/db_models/user.py b/{{cookiecutter.project_slug}}/backend/app/app/db_models/user.py new file mode 100755 index 0000000..5ad542a --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/db_models/user.py @@ -0,0 +1,29 @@ +# Import standard library packages +from datetime import datetime + +# Typings, for autocompletion (VS Code with Python plug-in) +from typing import List # noqa + +# Import app code +from app.db.base_class import Base +from app.models.base_relations import users_roles + +# Import installed packages +from sqlalchemy import Boolean, Column, DateTime, Integer, String +from sqlalchemy.orm import relationship + + +class User(Base): + # Own properties + id = Column(Integer, primary_key=True, index=True) + created_at = Column(DateTime, default=datetime.utcnow(), index=True) + first_name = Column(String, index=True) + last_name = Column(String, index=True) + email = Column(String, unique=True, index=True) + password = Column(String) + is_active = Column(Boolean(), default=True) + is_superuser = Column(Boolean(), default=False) + # Relationships + roles = relationship( + "Role", secondary=users_roles, back_populates="users" + ) # type: List[role.Role] diff --git a/{{cookiecutter.project_slug}}/backend/app/app/email-templates/build/new_account.html b/{{cookiecutter.project_slug}}/backend/app/app/email-templates/build/new_account.html new file mode 100644 index 0000000..395c7bd --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/email-templates/build/new_account.html @@ -0,0 +1,26 @@ +

{{ project_name }} - New Account
You have a new account:
Username: {{ username }}
Password: {{ password }}
Go to Dashboard

\ No newline at end of file diff --git a/{{cookiecutter.project_slug}}/backend/app/app/email-templates/build/reset_password.html b/{{cookiecutter.project_slug}}/backend/app/app/email-templates/build/reset_password.html new file mode 100644 index 0000000..7fbf368 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/email-templates/build/reset_password.html @@ -0,0 +1,26 @@ +

{{ project_name }} - Password Recovery
We received a request to recover the password for user {{ username }} with email {{ email }}
Reset your password by clicking the button below:
Reset Password
Or open the following link:

The reset password link / button will expire in {{ valid_hours }} hours.
If you didn't request a password recovery you can disregard this email.
\ No newline at end of file diff --git a/{{cookiecutter.project_slug}}/backend/app/app/email-templates/build/test_email.html b/{{cookiecutter.project_slug}}/backend/app/app/email-templates/build/test_email.html new file mode 100644 index 0000000..294d576 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/email-templates/build/test_email.html @@ -0,0 +1,25 @@ +

{{ project_name }}
Test email for: {{ email }}
\ No newline at end of file diff --git a/{{cookiecutter.project_slug}}/backend/app/app/email-templates/src/new_account.mjml b/{{cookiecutter.project_slug}}/backend/app/app/email-templates/src/new_account.mjml new file mode 100644 index 0000000..16c033b --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/email-templates/src/new_account.mjml @@ -0,0 +1,15 @@ + + + + + + {{ project_name }} - New Account + You have a new account: + Username: {{ username }} + Password: {{ password }} + Go to Dashboard + + + + + diff --git a/{{cookiecutter.project_slug}}/backend/app/app/email-templates/src/reset_password.mjml b/{{cookiecutter.project_slug}}/backend/app/app/email-templates/src/reset_password.mjml new file mode 100644 index 0000000..4f45ea2 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/email-templates/src/reset_password.mjml @@ -0,0 +1,19 @@ + + + + + + {{ project_name }} - Password Recovery + We received a request to recover the password for user {{ username }} + with email {{ email }} + Reset your password by clicking the button below: + Reset Password + Or open the following link: + {{ link }} + + The reset password link / button will expire in {{ valid_hours }} hours. + If you didn't request a password recovery you can disregard this email. + + + + diff --git a/{{cookiecutter.project_slug}}/backend/app/app/email-templates/src/test_email.mjml b/{{cookiecutter.project_slug}}/backend/app/app/email-templates/src/test_email.mjml new file mode 100644 index 0000000..5b9baa4 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/email-templates/src/test_email.mjml @@ -0,0 +1,11 @@ + + + + + + {{ project_name }} + Test email for: {{ email }} + + + + diff --git a/{{cookiecutter.project_slug}}/backend/app/app/main.py b/{{cookiecutter.project_slug}}/backend/app/app/main.py new file mode 100644 index 0000000..328dabd --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/main.py @@ -0,0 +1,26 @@ +from fastapi import FastAPI +from starlette.middleware.cors import CORSMiddleware + +from app.api.api_v1.api import api_router +from app.core.config import API_V1_STR, BACKEND_CORS_ORIGINS, PROJECT_NAME + +app = FastAPI(title=PROJECT_NAME, openapi_url="/api/v1/openapi.json") + +# CORS +origins = [] + +# Set all CORS enabled origins +if BACKEND_CORS_ORIGINS: + origins_raw = BACKEND_CORS_ORIGINS.split(",") + for origin in origins_raw: + use_origin = origin.strip() + origins.append(use_origin) + app.add_middleware( + CORSMiddleware, + allow_origins=origins, + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], + ), + +app.include_router(api_router, prefix=API_V1_STR) diff --git a/{{cookiecutter.project_slug}}/backend/app/app/models/__init__.py b/{{cookiecutter.project_slug}}/backend/app/app/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/{{cookiecutter.project_slug}}/backend/app/app/models/config.py b/{{cookiecutter.project_slug}}/backend/app/app/models/config.py new file mode 100644 index 0000000..7c55d2c --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/models/config.py @@ -0,0 +1 @@ +USERPROFILE_DOC_TYPE = "userprofile" diff --git a/{{cookiecutter.project_slug}}/backend/app/app/models/msg.py b/{{cookiecutter.project_slug}}/backend/app/app/models/msg.py new file mode 100644 index 0000000..945e0c6 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/models/msg.py @@ -0,0 +1,5 @@ +from pydantic import BaseModel + + +class Msg(BaseModel): + msg: str diff --git a/{{cookiecutter.project_slug}}/backend/app/app/models/role.py b/{{cookiecutter.project_slug}}/backend/app/app/models/role.py new file mode 100644 index 0000000..789013e --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/models/role.py @@ -0,0 +1,14 @@ +from enum import Enum +from typing import List + +from pydantic import BaseModel + +from app.core.config import ROLE_SUPERUSER + + +class RoleEnum(Enum): + superuser = ROLE_SUPERUSER + + +class Roles(BaseModel): + roles: List[RoleEnum] diff --git a/{{cookiecutter.project_slug}}/backend/app/app/models/token.py b/{{cookiecutter.project_slug}}/backend/app/app/models/token.py new file mode 100644 index 0000000..764765f --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/models/token.py @@ -0,0 +1,10 @@ +from pydantic import BaseModel + + +class Token(BaseModel): + access_token: str + token_type: str + + +class TokenPayload(BaseModel): + username: str = None diff --git a/{{cookiecutter.project_slug}}/backend/app/app/models/user.py b/{{cookiecutter.project_slug}}/backend/app/app/models/user.py new file mode 100644 index 0000000..0b5ab4c --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/models/user.py @@ -0,0 +1,48 @@ +from typing import List, Optional, Union + +from pydantic import BaseModel + +from app.models.config import USERPROFILE_DOC_TYPE +from app.models.role import RoleEnum + + +# Shared properties +class UserBase(BaseModel): + email: Optional[str] = None + admin_roles: Optional[List[Union[str, RoleEnum]]] = None + admin_channels: Optional[List[Union[str, RoleEnum]]] = None + disabled: Optional[bool] = None + + +class UserBaseInDB(UserBase): + username: str + full_name: Optional[str] = None + + +# Properties to receive via API on creation +class UserInCreate(UserBaseInDB): + password: str + admin_roles: List[Union[str, RoleEnum]] = [] + admin_channels: List[Union[str, RoleEnum]] = [] + disabled: bool = False + + +# Properties to receive via API on update +class UserInUpdate(UserBaseInDB): + password: Optional[str] = None + + +# Additional properties to return via API +class User(UserBaseInDB): + pass + + +# Additional properties stored in DB +class UserInDB(UserBaseInDB): + type: str = USERPROFILE_DOC_TYPE + hashed_password: str + + +class UserSyncIn(UserBase): + name: str + password: Optional[str] = None diff --git a/{{cookiecutter.project_slug}}/backend/app/app/search_index_definitions/users.json b/{{cookiecutter.project_slug}}/backend/app/app/search_index_definitions/users.json new file mode 100644 index 0000000..55c9a40 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/search_index_definitions/users.json @@ -0,0 +1,15 @@ +{ + "name": "users", + "type": "fulltext-alias", + "params": { + "targets": { + "users_01": {} + } + }, + "sourceType": "nil", + "sourceName": "", + "sourceUUID": "", + "sourceParams": null, + "planParams": {}, + "uuid": "" +} diff --git a/{{cookiecutter.project_slug}}/backend/app/app/search_index_definitions/users_01.json b/{{cookiecutter.project_slug}}/backend/app/app/search_index_definitions/users_01.json new file mode 100644 index 0000000..e297177 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/search_index_definitions/users_01.json @@ -0,0 +1,157 @@ +{ + "name": "users_01", + "type": "fulltext-index", + "params": { + "doc_config": { + "docid_prefix_delim": "", + "docid_regexp": "", + "mode": "type_field", + "type_field": "type" + }, + "mapping": { + "analysis": { + "analyzers": { + "userprofile": { + "token_filters": [ + "apostrophe", + "to_lower" + ], + "tokenizer": "unicode", + "type": "custom" + } + } + }, + "default_analyzer": "standard", + "default_datetime_parser": "dateTimeOptional", + "default_field": "_all", + "default_mapping": { + "dynamic": true, + "enabled": false + }, + "default_type": "_default", + "docvalues_dynamic": true, + "index_dynamic": true, + "store_dynamic": false, + "type_field": "_type", + "types": { + "userprofile": { + "dynamic": false, + "enabled": true, + "properties": { + "type": { + "enabled": true, + "dynamic": false, + "fields": [ + { + "name": "type", + "type": "text", + "analyzer": "keyword", + "store": false, + "index": true, + "include_term_vectors": false, + "include_in_all": false + } + ] + }, + "admin_channels": { + "enabled": true, + "dynamic": false, + "fields": [ + { + "analyzer": "keyword", + "include_in_all": true, + "include_term_vectors": true, + "index": true, + "name": "admin_channels", + "type": "text" + } + ] + }, + "admin_roles": { + "enabled": true, + "dynamic": false, + "fields": [ + { + "analyzer": "keyword", + "include_in_all": true, + "include_term_vectors": true, + "index": true, + "name": "admin_roles", + "type": "text" + } + ] + }, + "disabled": { + "enabled": true, + "dynamic": false, + "fields": [ + { + "include_in_all": true, + "include_term_vectors": true, + "index": true, + "name": "disabled", + "type": "boolean" + } + ] + }, + "email": { + "enabled": true, + "dynamic": false, + "fields": [ + { + "analyzer": "keyword", + "include_in_all": true, + "include_term_vectors": true, + "index": true, + "name": "email", + "type": "text" + } + ] + }, + "full_name": { + "enabled": true, + "dynamic": false, + "fields": [ + { + "analyzer": "standard", + "include_in_all": true, + "include_term_vectors": true, + "index": true, + "name": "full_name", + "type": "text" + } + ] + }, + "username": { + "enabled": true, + "dynamic": false, + "fields": [ + { + "analyzer": "keyword", + "include_in_all": true, + "include_term_vectors": true, + "index": true, + "name": "username", + "type": "text" + } + ] + } + } + } + } + }, + "store": { + "indexType": "scorch", + "kvStoreName": "" + } + }, + "sourceType": "couchbase", + "sourceName": "app", + "sourceUUID": "", + "sourceParams": {}, + "planParams": { + "maxPartitionsPerPIndex": 171, + "numReplicas": 0 + }, + "uuid": "" +} \ No newline at end of file diff --git a/{{cookiecutter.project_slug}}/backend/app/app/tests/.gitignore b/{{cookiecutter.project_slug}}/backend/app/app/tests/.gitignore new file mode 100755 index 0000000..16d3c4d --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/tests/.gitignore @@ -0,0 +1 @@ +.cache diff --git a/{{cookiecutter.project_slug}}/backend/app/app/tests/__init__.py b/{{cookiecutter.project_slug}}/backend/app/app/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/{{cookiecutter.project_slug}}/backend/app/app/tests/api/__init__.py b/{{cookiecutter.project_slug}}/backend/app/app/tests/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/{{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/__init__.py b/{{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/{{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/test_celery.py b/{{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/test_celery.py new file mode 100644 index 0000000..eb48030 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/test_celery.py @@ -0,0 +1,16 @@ +import requests + +from app.core import config +from app.tests.utils.utils import get_server_api + + +def test_celery_worker_test(superuser_token_headers): + server_api = get_server_api() + data = {"msg": "test"} + r = requests.post( + f"{server_api}{config.API_V1_STR}/test-celery/", + json=data, + headers=superuser_token_headers, + ) + response = r.json() + assert response["msg"] == "Word received" diff --git a/{{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/test_token.py b/{{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/test_token.py new file mode 100644 index 0000000..08ba2eb --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/test_token.py @@ -0,0 +1,30 @@ +import requests + +from app.core import config +from app.tests.utils.utils import get_server_api + + +def test_get_access_token(): + server_api = get_server_api() + login_data = { + "username": config.FIRST_SUPERUSER, + "password": config.FIRST_SUPERUSER_PASSWORD, + } + r = requests.post( + f"{server_api}{config.API_V1_STR}/login/access-token", data=login_data + ) + tokens = r.json() + assert r.status_code == 200 + assert "access_token" in tokens + assert tokens["access_token"] + + +def test_use_access_token(superuser_token_headers): + server_api = get_server_api() + r = requests.post( + f"{server_api}{config.API_V1_STR}/login/test-token", + headers=superuser_token_headers, + ) + result = r.json() + assert r.status_code == 200 + assert "username" in result diff --git a/{{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/test_user.py b/{{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/test_user.py new file mode 100644 index 0000000..94ae472 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/tests/api/api_v1/test_user.py @@ -0,0 +1,112 @@ +import requests + +from app.core import config +from app.crud.user import get_user, upsert_user +from app.db.database import get_default_bucket +from app.models.user import UserInCreate +from app.tests.utils.user import user_authentication_headers +from app.tests.utils.utils import get_server_api, random_lower_string + + +def test_get_users_superuser_me(superuser_token_headers): + server_api = get_server_api() + r = requests.get( + f"{server_api}{config.API_V1_STR}/users/me", headers=superuser_token_headers + ) + current_user = r.json() + assert current_user + assert current_user["disabled"] is False + assert "superuser" in current_user["admin_roles"] + assert current_user["username"] == config.FIRST_SUPERUSER + + +def test_create_user_new_email(superuser_token_headers): + server_api = get_server_api() + username = random_lower_string() + password = random_lower_string() + data = {"username": username, "password": password} + r = requests.post( + f"{server_api}{config.API_V1_STR}/users/", + headers=superuser_token_headers, + json=data, + ) + assert 200 <= r.status_code < 300 + created_user = r.json() + bucket = get_default_bucket() + user = get_user(bucket, username) + assert user.username == created_user["username"] + + +def test_get_existing_user(superuser_token_headers): + server_api = get_server_api() + username = random_lower_string() + password = random_lower_string() + user_in = UserInCreate(username=username, email=username, password=password) + bucket = get_default_bucket() + user = upsert_user(bucket, user_in, persist_to=1) + r = requests.get( + f"{server_api}{config.API_V1_STR}/users/{username}", + headers=superuser_token_headers, + ) + assert 200 <= r.status_code < 300 + api_user = r.json() + user = get_user(bucket, username) + assert user.username == api_user["username"] + + +def test_create_user_existing_username(superuser_token_headers): + server_api = get_server_api() + username = random_lower_string() + # username = email + password = random_lower_string() + user_in = UserInCreate(username=username, email=username, password=password) + bucket = get_default_bucket() + user = upsert_user(bucket, user_in, persist_to=1) + data = {"username": username, "password": password} + r = requests.post( + f"{server_api}{config.API_V1_STR}/users/", + headers=superuser_token_headers, + json=data, + ) + created_user = r.json() + assert r.status_code == 400 + assert "_id" not in created_user + + +def test_create_user_by_normal_user(): + server_api = get_server_api() + username = random_lower_string() + password = random_lower_string() + user_in = UserInCreate(username=username, email=username, password=password) + bucket = get_default_bucket() + user = upsert_user(bucket, user_in, persist_to=1) + user_token_headers = user_authentication_headers(server_api, username, password) + data = {"username": username, "password": password} + r = requests.post( + f"{server_api}{config.API_V1_STR}/users/", headers=user_token_headers, json=data + ) + assert r.status_code == 400 + + +def test_retrieve_users(superuser_token_headers): + server_api = get_server_api() + username = random_lower_string() + password = random_lower_string() + user_in = UserInCreate(username=username, email=username, password=password) + bucket = get_default_bucket() + user = upsert_user(bucket, user_in, persist_to=1) + + username2 = random_lower_string() + password2 = random_lower_string() + user_in2 = UserInCreate(username=username2, email=username2, password=password2) + user2 = upsert_user(bucket, user_in, persist_to=1) + + r = requests.get( + f"{server_api}{config.API_V1_STR}/users/", headers=superuser_token_headers + ) + all_users = r.json() + + assert len(all_users) > 1 + for user in all_users: + assert "username" in user + assert "admin_roles" in user diff --git a/{{cookiecutter.project_slug}}/backend/app/app/tests/conftest.py b/{{cookiecutter.project_slug}}/backend/app/app/tests/conftest.py new file mode 100644 index 0000000..0e3c044 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/tests/conftest.py @@ -0,0 +1,13 @@ +import pytest + +from app.tests.utils.utils import get_server_api, get_superuser_token_headers + + +@pytest.fixture(scope="module") +def server_api(): + return get_server_api() + + +@pytest.fixture(scope="module") +def superuser_token_headers(): + return get_superuser_token_headers() diff --git a/{{cookiecutter.project_slug}}/backend/app/app/tests/crud/__init__.py b/{{cookiecutter.project_slug}}/backend/app/app/tests/crud/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/{{cookiecutter.project_slug}}/backend/app/app/tests/crud/test_get_ids.py b/{{cookiecutter.project_slug}}/backend/app/app/tests/crud/test_get_ids.py new file mode 100644 index 0000000..038e838 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/tests/crud/test_get_ids.py @@ -0,0 +1,7 @@ +from app.crud.user import get_user_doc_id + + +def test_get_user_id(): + username = "johndoe@example.com" + user_id = get_user_doc_id(username) + assert user_id == "userprofile::johndoe@example.com" diff --git a/{{cookiecutter.project_slug}}/backend/app/app/tests/crud/test_user.py b/{{cookiecutter.project_slug}}/backend/app/app/tests/crud/test_user.py new file mode 100644 index 0000000..27c0e1b --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/tests/crud/test_user.py @@ -0,0 +1,105 @@ +from fastapi.encoders import jsonable_encoder + +from app.crud.user import ( + authenticate_user, + check_if_user_is_active, + check_if_user_is_superuser, + get_user, + upsert_user, +) +from app.db.database import get_default_bucket +from app.models.role import RoleEnum +from app.models.user import UserInCreate +from app.tests.utils.utils import random_lower_string + + +def test_create_user(): + email = random_lower_string() + password = random_lower_string() + user_in = UserInCreate(username=email, email=email, password=password) + bucket = get_default_bucket() + user = upsert_user(bucket, user_in, persist_to=1) + assert hasattr(user, "username") + assert user.username == email + assert hasattr(user, "hashed_password") + assert hasattr(user, "type") + assert user.type == "userprofile" + + +def test_authenticate_user(): + email = random_lower_string() + password = random_lower_string() + user_in = UserInCreate(username=email, email=email, password=password) + bucket = get_default_bucket() + user = upsert_user(bucket, user_in, persist_to=1) + authenticated_user = authenticate_user(bucket, email, password) + assert authenticated_user + assert user.username == authenticated_user.username + + +def test_not_authenticate_user(): + email = random_lower_string() + password = random_lower_string() + bucket = get_default_bucket() + user = authenticate_user(bucket, email, password) + assert user is False + + +def test_check_if_user_is_active(): + email = random_lower_string() + password = random_lower_string() + user_in = UserInCreate(username=email, email=email, password=password) + bucket = get_default_bucket() + user = upsert_user(bucket, user_in, persist_to=1) + is_active = check_if_user_is_active(user) + assert is_active is True + + +def test_check_if_user_is_active_inactive(): + email = random_lower_string() + password = random_lower_string() + user_in = UserInCreate( + username=email, email=email, password=password, disabled=True + ) + bucket = get_default_bucket() + user = upsert_user(bucket, user_in, persist_to=1) + is_active = check_if_user_is_active(user) + assert is_active is False + + +def test_check_if_user_is_superuser(): + email = random_lower_string() + password = random_lower_string() + user_in = UserInCreate( + username=email, email=email, password=password, admin_roles=[RoleEnum.superuser] + ) + bucket = get_default_bucket() + user = upsert_user(bucket, user_in, persist_to=1) + is_superuser = check_if_user_is_superuser(user) + assert is_superuser is True + + +def test_check_if_user_is_superuser_normal_user(): + username = random_lower_string() + password = random_lower_string() + user_in = UserInCreate(username=username, email=username, password=password) + bucket = get_default_bucket() + user = upsert_user(bucket, user_in, persist_to=1) + is_superuser = check_if_user_is_superuser(user) + assert is_superuser is False + + +def test_get_user(): + password = random_lower_string() + username = random_lower_string() + user_in = UserInCreate( + username=username, + email=username, + password=password, + admin_roles=[RoleEnum.superuser], + ) + bucket = get_default_bucket() + user = upsert_user(bucket, user_in, persist_to=1) + user_2 = get_user(bucket, username) + assert user.username == user_2.username + assert jsonable_encoder(user) == jsonable_encoder(user_2) diff --git a/{{cookiecutter.project_slug}}/backend/app/app/tests/utils/__init__.py b/{{cookiecutter.project_slug}}/backend/app/app/tests/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/{{cookiecutter.project_slug}}/backend/app/app/tests/utils/user.py b/{{cookiecutter.project_slug}}/backend/app/app/tests/utils/user.py new file mode 100644 index 0000000..9f8009f --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/tests/utils/user.py @@ -0,0 +1,13 @@ +import requests + +from app.core import config + + +def user_authentication_headers(server_api, email, password): + data = {"username": email, "password": password} + + r = requests.post(f"{server_api}{config.API_V1_STR}/login/access-token", data=data) + response = r.json() + auth_token = response["access_token"] + headers = {"Authorization": f"Bearer {auth_token}"} + return headers diff --git a/{{cookiecutter.project_slug}}/backend/app/app/tests/utils/utils.py b/{{cookiecutter.project_slug}}/backend/app/app/tests/utils/utils.py new file mode 100644 index 0000000..9a8dd16 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/tests/utils/utils.py @@ -0,0 +1,31 @@ +import random +import string + +import requests + +from app.core import config + + +def random_lower_string(): + return "".join(random.choices(string.ascii_lowercase, k=32)) + + +def get_server_api(): + server_name = f"http://{config.SERVER_NAME}" + return server_name + + +def get_superuser_token_headers(): + server_api = get_server_api() + login_data = { + "username": config.FIRST_SUPERUSER, + "password": config.FIRST_SUPERUSER_PASSWORD, + } + r = requests.post( + f"{server_api}{config.API_V1_STR}/login/access-token", data=login_data + ) + tokens = r.json() + a_token = tokens["access_token"] + headers = {"Authorization": f"Bearer {a_token}"} + # superuser_token_headers = headers + return headers diff --git a/{{cookiecutter.project_slug}}/backend/app/app/tests_pre_start.py b/{{cookiecutter.project_slug}}/backend/app/app/tests_pre_start.py new file mode 100644 index 0000000..476659f --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/tests_pre_start.py @@ -0,0 +1,35 @@ +import logging + +from tenacity import after_log, before_log, retry, stop_after_attempt, wait_fixed + +from app.db.external_session import db_session +from app.tests.api.api_v1.token.test_token import test_get_access_token + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +max_tries = 60 * 5 # 5 minutes +wait_seconds = 1 + + +@retry( + stop=stop_after_attempt(max_tries), + wait=wait_fixed(wait_seconds), + before=before_log(logger, logging.INFO), + after=after_log(logger, logging.WARN), +) +def init(): + # Try to create session to check if DB is awake + db_session.execute("SELECT 1") + # Wait for API to be awake, run one simple tests to authenticate + test_get_access_token() + + +def main(): + logger.info("Initializing service") + init() + logger.info("Service finished initializing") + + +if __name__ == "__main__": + main() diff --git a/{{cookiecutter.project_slug}}/backend/app/app/utils.py b/{{cookiecutter.project_slug}}/backend/app/app/utils.py new file mode 100644 index 0000000..b9347cb --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/utils.py @@ -0,0 +1,126 @@ +import logging +from datetime import datetime, timedelta +from pathlib import Path +from typing import Union + +import emails +import jwt +from emails.template import JinjaTemplate +from jwt.exceptions import InvalidTokenError + +from app.core.config import ( + EMAIL_RESET_TOKEN_EXPIRE_HOURS, + EMAIL_TEMPLATES_DIR, + EMAILS_ENABLED, + EMAILS_FROM_EMAIL, + EMAILS_FROM_NAME, + PROJECT_NAME, + SECRET_KEY, + SERVER_HOST, + SMTP_HOST, + SMTP_PASSWORD, + SMTP_PORT, + SMTP_TLS, + SMTP_USER, +) + +password_reset_jwt_subject = "preset" + + +def send_email(email_to: str, subject_template="", html_template="", environment={}): + assert EMAILS_ENABLED, "no provided configuration for email variables" + message = emails.Message( + subject=JinjaTemplate(subject_template), + html=JinjaTemplate(html_template), + mail_from=(EMAILS_FROM_NAME, EMAILS_FROM_EMAIL), + ) + smtp_options = {"host": SMTP_HOST, "port": SMTP_PORT} + if SMTP_TLS: + smtp_options["tls"] = True + if SMTP_USER: + smtp_options["user"] = SMTP_USER + if SMTP_PASSWORD: + smtp_options["password"] = SMTP_PASSWORD + response = message.send(to=email_to, render=environment, smtp=smtp_options) + logging.info(f"send email result: {response}") + + +def send_test_email(email_to: str): + subject = f"{PROJECT_NAME} - Test email" + with open(Path(EMAIL_TEMPLATES_DIR) / "test_email.html") as f: + template_str = f.read() + send_email( + email_to=email_to, + subject_template=subject, + html_template=template_str, + environment={"project_name": PROJECT_NAME, "email": email_to}, + ) + + +def send_reset_password_email(email_to: str, username: str, token: str): + subject = f"{PROJECT_NAME} - Password recovery for user {username}" + with open(Path(EMAIL_TEMPLATES_DIR) / "reset_password.html") as f: + template_str = f.read() + if hasattr(token, "decode"): + use_token = token.decode() + else: + use_token = token + link = f"{SERVER_HOST}/reset-password?token={use_token}" + send_email( + email_to=email_to, + subject_template=subject, + html_template=template_str, + environment={ + "project_name": PROJECT_NAME, + "username": username, + "email": email_to, + "valid_hours": EMAIL_RESET_TOKEN_EXPIRE_HOURS, + "link": link, + }, + ) + + +def send_new_account_email(email_to: str, username: str, password: str): + subject = f"{PROJECT_NAME} - New acccount for user {username}" + with open(Path(EMAIL_TEMPLATES_DIR) / "new_account.html") as f: + template_str = f.read() + link = f"{SERVER_HOST}" + send_email( + email_to=email_to, + subject_template=subject, + html_template=template_str, + environment={ + "project_name": PROJECT_NAME, + "username": username, + "password": password, + "email": email_to, + "link": link, + }, + ) + + +def generate_password_reset_token(username): + delta = timedelta(hours=EMAIL_RESET_TOKEN_EXPIRE_HOURS) + now = datetime.utcnow() + expires = now + delta + exp = expires.timestamp() + encoded_jwt = jwt.encode( + { + "exp": exp, + "nbf": now, + "sub": password_reset_jwt_subject, + "username": username, + }, + SECRET_KEY, + algorithm="HS256", + ) + return encoded_jwt + + +def verify_password_reset_token(token) -> Union[str, bool]: + try: + decoded_token = jwt.decode(token, SECRET_KEY, algorithms=["HS256"]) + assert decoded_token["sub"] == password_reset_jwt_subject + return decoded_token["username"] + except InvalidTokenError: + return False diff --git a/{{cookiecutter.project_slug}}/backend/app/app/worker.py b/{{cookiecutter.project_slug}}/backend/app/app/worker.py new file mode 100644 index 0000000..89a2a06 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/app/worker.py @@ -0,0 +1,19 @@ +# Import standard library modules + + +# Import installed packages +from raven import Client + +from app.core.celery_app import celery_app + +# Import app code +# Absolute imports for Hydrogen (Jupyter Kernel) compatibility +from app.core.config import SENTRY_DSN + +client_sentry = Client(SENTRY_DSN) + + +@celery_app.task(acks_late=True) +def test_celery(word: str): + print("test task") + return f"test task return {word}" diff --git a/{{cookiecutter.project_slug}}/backend/app/backend-live.sh b/{{cookiecutter.project_slug}}/backend/app/backend-live.sh new file mode 100644 index 0000000..c092307 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/backend-live.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +uvicorn app.main:app --host 0.0.0.0 --port 80 --debug diff --git a/{{cookiecutter.project_slug}}/backend/app/backend-start.sh b/{{cookiecutter.project_slug}}/backend/app/backend-start.sh new file mode 100644 index 0000000..7a7893f --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/backend-start.sh @@ -0,0 +1,27 @@ +#! /usr/bin/env bash + +set -e + +# Let the DB start +python /app/app/backend_pre_start.py + + +LOG_LEVEL=info +# Uncomment to squeeze performance in exchange of logs +# LOG_LEVEL=warning + +# Get CPU cores +CORES=$(nproc --all) +# Read env var WORKERS_PER_CORE with default of 2 +WORKERS_PER_CORE_PERCENT=${WORKERS_PER_CORE_PERCENT:-200} +# Compute DEFAULT_WEB_CONCURRENCY as CPU cores * workers per core +DEFAULT_WEB_CONCURRENCY=$(( ($CORES * $WORKERS_PER_CORE_PERCENT) / 100 )) +# Minimum default of workers is 1 +if [ "$DEFAULT_WEB_CONCURRENCY" -lt 1 ]; then + DEFAULT_WEB_CONCURRENCY=1 +fi +# Read WEB_CONCURRENCY env var, with default of computed value +WEB_CONCURRENCY=${WEB_CONCURRENCY:-$DEFAULT_WEB_CONCURRENCY} +echo "Using these many workers: $WEB_CONCURRENCY" + +gunicorn -k uvicorn.workers.UvicornWorker --log-level $LOG_LEVEL app.main:app --bind 0.0.0.0:80 diff --git a/{{cookiecutter.project_slug}}/backend/app/prestart.sh b/{{cookiecutter.project_slug}}/backend/app/prestart.sh new file mode 100644 index 0000000..f95ea91 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/prestart.sh @@ -0,0 +1,4 @@ +#! /usr/bin/env bash + +# Let the DB start +python /app/app/backend_pre_start.py diff --git a/{{cookiecutter.project_slug}}/backend/app/scripts/lint.sh b/{{cookiecutter.project_slug}}/backend/app/scripts/lint.sh new file mode 100644 index 0000000..a7c6da9 --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/scripts/lint.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -x + +autoflake --remove-all-unused-imports --recursive --remove-unused-variables --in-place app --exclude=__init__.py +isort --multi-line=3 --trailing-comma --force-grid-wrap=0 --combine-as --line-width 88 --recursive --apply app +black app diff --git a/{{cookiecutter.project_slug}}/backend/app/tests-start.sh b/{{cookiecutter.project_slug}}/backend/app/tests-start.sh new file mode 100644 index 0000000..1065fdc --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/tests-start.sh @@ -0,0 +1,6 @@ +#! /usr/bin/env bash +set -e + +python /app/app/tests_pre_start.py + +pytest /app/app/tests/ diff --git a/{{cookiecutter.project_slug}}/backend/app/worker-start.sh b/{{cookiecutter.project_slug}}/backend/app/worker-start.sh new file mode 100644 index 0000000..172f08e --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/app/worker-start.sh @@ -0,0 +1,6 @@ +#! /usr/bin/env bash +set -e + +python /app/app/celeryworker_pre_start.py + +celery worker -A app.worker -l info -Q main-queue -c 1 diff --git a/{{cookiecutter.project_slug}}/backend/backend.dockerfile b/{{cookiecutter.project_slug}}/backend/backend.dockerfile new file mode 100644 index 0000000..b59694f --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/backend.dockerfile @@ -0,0 +1,19 @@ +FROM python:3.6 + +RUN pip install celery==4.2.1 passlib[bcrypt] tenacity requests pydantic emails fastapi>=0.2.0 uvicorn gunicorn pyjwt python-multipart email_validator jinja2 psycopg2-binary alembic SQLAlchemy + +# For development, Jupyter remote kernel, Hydrogen +# Using inside the container: +# jupyter notebook --ip=0.0.0.0 --allow-root +ARG env=prod +RUN bash -c "if [ $env == 'dev' ] ; then pip install jupyter ; fi" +EXPOSE 8888 + +COPY ./app /app +WORKDIR /app/ + +ENV PYTHONPATH=/app + +EXPOSE 80 + +CMD ["bash", "/app/backend-start.sh"] diff --git a/{{cookiecutter.project_slug}}/backend/celeryworker.dockerfile b/{{cookiecutter.project_slug}}/backend/celeryworker.dockerfile new file mode 100644 index 0000000..cd9be2d --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/celeryworker.dockerfile @@ -0,0 +1,23 @@ +FROM python:3.6 + +RUN pip install raven celery==4.2.1 passlib[bcrypt] tenacity requests fastapi>=0.1.13 pydantic emails pyjwt email_validator jinja2 psycopg2-binary alembic SQLAlchemy + +# For development, Jupyter remote kernel, Hydrogen +# Using inside the container: +# jupyter notebook --ip=0.0.0.0 --allow-root +ARG env=prod +RUN bash -c "if [ $env == 'dev' ] ; then pip install jupyter ; fi" +EXPOSE 8888 + +ENV C_FORCE_ROOT=1 + +COPY ./app /app +WORKDIR /app + +ENV PYTHONPATH=/app + +COPY ./app/worker-start.sh /worker-start.sh + +RUN chmod +x /worker-start.sh + +CMD ["bash", "/worker-start.sh"] diff --git a/{{cookiecutter.project_slug}}/backend/tests.dockerfile b/{{cookiecutter.project_slug}}/backend/tests.dockerfile new file mode 100644 index 0000000..3a0c7ee --- /dev/null +++ b/{{cookiecutter.project_slug}}/backend/tests.dockerfile @@ -0,0 +1,24 @@ +FROM python:3.6 + +RUN pip install requests pytest tenacity passlib[bcrypt] pydantic fastapi>=0.1.13 psycopg2-binary SQLAlchemy + +# For development, Jupyter remote kernel, Hydrogen +# Using inside the container: +# jupyter notebook --ip=0.0.0.0 --allow-root +ARG env=prod +RUN bash -c "if [ $env == 'dev' ] ; then pip install jupyter ; fi" +EXPOSE 8888 + +COPY ./app /app + +ENV PYTHONPATH=/app + +COPY ./app/tests-start.sh /tests-start.sh + +RUN chmod +x /tests-start.sh + +# This will make the container wait, doing nothing, but alive +CMD ["bash", "-c", "while true; do sleep 1; done"] + +# Afterwards you can exec a command /tests-start.sh in the live container, like: +# docker exec -it backend-tests /tests-start.sh diff --git a/{{cookiecutter.project_slug}}/cookiecutter-config-file.yml b/{{cookiecutter.project_slug}}/cookiecutter-config-file.yml new file mode 100644 index 0000000..a83f4de --- /dev/null +++ b/{{cookiecutter.project_slug}}/cookiecutter-config-file.yml @@ -0,0 +1,31 @@ +default_context: + project_name: '{{ cookiecutter.project_name }}' + project_slug: '{{ cookiecutter.project_slug }}' + domain_main: '{{ cookiecutter.domain_main }}' + domain_staging: '{{ cookiecutter.domain_staging }}' + docker_swarm_stack_name_main: '{{ cookiecutter.docker_swarm_stack_name_main }}' + docker_swarm_stack_name_staging: '{{ cookiecutter.docker_swarm_stack_name_staging }}' + secret_key: '{{ cookiecutter.secret_key }}' + first_superuser: '{{ cookiecutter.first_superuser }}' + first_superuser_password: '{{ cookiecutter.first_superuser_password }}' + backend_cors_origins: '{{ cookiecutter.backend_cors_origins }}' + smtp_port: '{{ cookiecutter.smtp_port }}' + smtp_host: '{{ cookiecutter.smtp_host }}' + smtp_user: '{{ cookiecutter.smtp_user }}' + smtp_password: '{{ cookiecutter.smtp_password }}' + smtp_emails_from_email: '{{ cookiecutter.smtp_emails_from_email }}' + postgres_password: '{{ cookiecutter.postgres_password }}' + pgadmin_default_user: '{{ cookiecutter.pgadmin_default_user }}' + pgadmin_default_user_password: '{{ cookiecutter.pgadmin_default_user_password }}' + traefik_constraint_tag: '{{ cookiecutter.traefik_constraint_tag }}' + traefik_constraint_tag_staging: '{{ cookiecutter.traefik_constraint_tag_staging }}' + traefik_public_network: '{{ cookiecutter.traefik_public_network }}' + traefik_public_constraint_tag: '{{ cookiecutter.traefik_public_constraint_tag }}' + flower_auth: '{{ cookiecutter.flower_auth }}' + sentry_dsn: '{{ cookiecutter.sentry_dsn }}' + docker_image_prefix: '{{ cookiecutter.docker_image_prefix }}' + docker_image_backend: '{{ cookiecutter.docker_image_backend }}' + docker_image_celeryworker: '{{ cookiecutter.docker_image_celeryworker }}' + docker_image_frontend: '{{ cookiecutter.docker_image_frontend }}' + _copy_without_render: [frontend/src/**/*.html, frontend/src/**/*.vue, frontend/node_modules/*, backend/app/app/email-templates/**] + _template: ./ diff --git a/{{cookiecutter.project_slug}}/docker-compose.deploy.build.yml b/{{cookiecutter.project_slug}}/docker-compose.deploy.build.yml new file mode 100644 index 0000000..178a164 --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.deploy.build.yml @@ -0,0 +1,15 @@ +version: '3.3' +services: + backend: + build: + context: ./backend + dockerfile: backend.dockerfile + celeryworker: + build: + context: ./backend + dockerfile: celeryworker.dockerfile + frontend: + build: + context: ./frontend + args: + FRONTEND_ENV: ${FRONTEND_ENV-production} diff --git a/{{cookiecutter.project_slug}}/docker-compose.deploy.command.yml b/{{cookiecutter.project_slug}}/docker-compose.deploy.command.yml new file mode 100644 index 0000000..141ee40 --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.deploy.command.yml @@ -0,0 +1,11 @@ +version: '3.3' +services: + proxy: + command: --docker \ + --docker.swarmmode \ + --docker.watch \ + --docker.exposedbydefault=false \ + --constraints=tag==${TRAEFIK_TAG} \ + --logLevel=INFO \ + --accessLog \ + --web diff --git a/{{cookiecutter.project_slug}}/docker-compose.deploy.images.yml b/{{cookiecutter.project_slug}}/docker-compose.deploy.images.yml new file mode 100644 index 0000000..f68f78d --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.deploy.images.yml @@ -0,0 +1,8 @@ +version: '3.3' +services: + backend: + image: '${DOCKER_IMAGE_BACKEND}:${TAG-latest}' + celeryworker: + image: '${DOCKER_IMAGE_CELERYWORKER}:${TAG-latest}' + frontend: + image: '${DOCKER_IMAGE_FRONTEND}:${TAG-latest}' diff --git a/{{cookiecutter.project_slug}}/docker-compose.deploy.labels.yml b/{{cookiecutter.project_slug}}/docker-compose.deploy.labels.yml new file mode 100644 index 0000000..8f3c675 --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.deploy.labels.yml @@ -0,0 +1,66 @@ +version: '3.3' +services: + pgadmin: + deploy: + labels: + - traefik.frontend.rule=Host:pgadmin.${DOMAIN} + - traefik.enable=true + - traefik.port=5050 + - traefik.tags=${TRAEFIK_PUBLIC_TAG} + - traefik.docker.network=${TRAEFIK_PUBLIC_NETWORK} + # Traefik service that listens to HTTP + - traefik.redirectorservice.frontend.entryPoints=http + - traefik.redirectorservice.frontend.redirect.entryPoint=https + # Traefik service that listens to HTTPS + - traefik.webservice.frontend.entryPoints=https + proxy: + deploy: + labels: + # For the configured domain + - traefik.frontend.rule=Host:${DOMAIN} + # For a domain with and without 'www' + # Comment the previous line above and un-comment the line below + # - "traefik.frontend.rule=Host:www.${DOMAIN},${DOMAIN}" + - traefik.enable=true + - traefik.port=80 + - traefik.tags=${TRAEFIK_PUBLIC_TAG} + - traefik.docker.network=${TRAEFIK_PUBLIC_NETWORK} + # Traefik service that listens to HTTP + - traefik.servicehttp.frontend.entryPoints=http + - traefik.servicehttp.frontend.redirect.entryPoint=https + # Traefik service that listens to HTTPS + - traefik.servicehttps.frontend.entryPoints=https + # Uncomment the config line below to detect and redirect www to non-www (or the contrary) + # The lines above for traefik.frontend.rule are needed too + # - "traefik.servicehttps.frontend.redirect.regex=^https?://(www.)?(${DOMAIN})/(.*)" + # To redirect from non-www to www un-comment the line below + # - "traefik.servicehttps.frontend.redirect.replacement=https://www.${DOMAIN}/$$3" + # To redirect from www to non-www un-comment the line below + # - "traefik.servicehttps.frontend.redirect.replacement=https://${DOMAIN}/$$3" + flower: + deploy: + labels: + - traefik.frontend.rule=Host:flower.${DOMAIN} + - traefik.enable=true + - traefik.port=5555 + - traefik.tags=${TRAEFIK_PUBLIC_TAG} + - traefik.docker.network=${TRAEFIK_PUBLIC_NETWORK} + # Traefik service that listens to HTTP + - traefik.redirectorservice.frontend.entryPoints=http + - traefik.redirectorservice.frontend.redirect.entryPoint=https + # Traefik service that listens to HTTPS + - traefik.webservice.frontend.entryPoints=https + backend: + deploy: + labels: + - traefik.frontend.rule=PathPrefix:/api,/docs,/redoc + - traefik.enable=true + - traefik.port=80 + - traefik.tags=${TRAEFIK_TAG} + frontend: + deploy: + labels: + - traefik.frontend.rule=PathPrefix:/ + - traefik.enable=true + - traefik.port=80 + - traefik.tags=${TRAEFIK_TAG} diff --git a/{{cookiecutter.project_slug}}/docker-compose.deploy.networks.yml b/{{cookiecutter.project_slug}}/docker-compose.deploy.networks.yml new file mode 100644 index 0000000..6d204cb --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.deploy.networks.yml @@ -0,0 +1,18 @@ +version: '3.3' +services: + pgadmin: + networks: + - ${TRAEFIK_PUBLIC_NETWORK} + - default + proxy: + networks: + - ${TRAEFIK_PUBLIC_NETWORK} + - default + flower: + networks: + - ${TRAEFIK_PUBLIC_NETWORK} + - default + +networks: + {{cookiecutter.traefik_public_network}}: + external: true diff --git a/{{cookiecutter.project_slug}}/docker-compose.deploy.volumes-placement.yml b/{{cookiecutter.project_slug}}/docker-compose.deploy.volumes-placement.yml new file mode 100644 index 0000000..86bbfd0 --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.deploy.volumes-placement.yml @@ -0,0 +1,17 @@ +version: '3.3' +services: + db: + volumes: + - app-db-data:/var/lib/postgresql/data/pgdata + deploy: + placement: + constraints: + - node.labels.${STACK_NAME}.app-db-data == true + proxy: + deploy: + placement: + constraints: + - node.role == manager + +volumes: + app-db-data: diff --git a/{{cookiecutter.project_slug}}/docker-compose.dev.build.yml b/{{cookiecutter.project_slug}}/docker-compose.dev.build.yml new file mode 100644 index 0000000..6f06338 --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.dev.build.yml @@ -0,0 +1,25 @@ +version: '3.3' +services: + backend: + build: + context: ./backend + dockerfile: backend.dockerfile + args: + env: dev + celeryworker: + build: + context: ./backend + dockerfile: celeryworker.dockerfile + args: + env: dev + backend-tests: + build: + context: ./backend + dockerfile: tests.dockerfile + args: + env: dev + frontend: + build: + context: ./frontend + args: + FRONTEND_ENV: dev diff --git a/{{cookiecutter.project_slug}}/docker-compose.dev.command.yml b/{{cookiecutter.project_slug}}/docker-compose.dev.command.yml new file mode 100644 index 0000000..1440009 --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.dev.command.yml @@ -0,0 +1,12 @@ +version: '3.3' +services: + proxy: + command: --docker \ + --docker.watch \ + --docker.exposedbydefault=false \ + --constraints=tag==${TRAEFIK_TAG} \ + --logLevel=DEBUG \ + --accessLog \ + --web + # backend: + # command: bash -c "while true; do sleep 1; done" # Infinite loop to keep container live doing nothing diff --git a/{{cookiecutter.project_slug}}/docker-compose.dev.env.yml b/{{cookiecutter.project_slug}}/docker-compose.dev.env.yml new file mode 100644 index 0000000..9118b25 --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.dev.env.yml @@ -0,0 +1,14 @@ +version: '3.3' +services: + backend: + environment: + - 'JUPYTER=jupyter notebook --ip=0.0.0.0 --allow-root' + - SERVER_HOST=http://${DOMAIN} + celeryworker: + environment: + - RUN=celery worker -A app.worker -l info -Q main-queue -c 1 + - JUPYTER=jupyter notebook --ip=0.0.0.0 --allow-root + - SERVER_HOST=http://${DOMAIN} + backend-tests: + environment: + - JUPYTER=jupyter notebook --ip=0.0.0.0 --allow-root diff --git a/{{cookiecutter.project_slug}}/docker-compose.dev.labels.yml b/{{cookiecutter.project_slug}}/docker-compose.dev.labels.yml new file mode 100644 index 0000000..46799e6 --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.dev.labels.yml @@ -0,0 +1,19 @@ +version: '3.3' +services: + proxy: + labels: + - traefik.frontend.rule=Host:${DOMAIN} + - traefik.enable=true + - traefik.port=80 + backend: + labels: + - traefik.frontend.rule=PathPrefix:/api,/docs,/redoc + - traefik.enable=true + - traefik.port=80 + - traefik.tags=${TRAEFIK_TAG} + frontend: + labels: + - traefik.frontend.rule=PathPrefix:/ + - traefik.enable=true + - traefik.port=80 + - traefik.tags=${TRAEFIK_TAG} diff --git a/{{cookiecutter.project_slug}}/docker-compose.dev.networks.yml b/{{cookiecutter.project_slug}}/docker-compose.dev.networks.yml new file mode 100644 index 0000000..3a3990f --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.dev.networks.yml @@ -0,0 +1,7 @@ +version: '3.3' +services: + backend: + networks: + default: + aliases: + - ${DOMAIN} diff --git a/{{cookiecutter.project_slug}}/docker-compose.dev.ports.yml b/{{cookiecutter.project_slug}}/docker-compose.dev.ports.yml new file mode 100644 index 0000000..af26b17 --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.dev.ports.yml @@ -0,0 +1,15 @@ +version: '3.3' +services: + pgadmin: + ports: + - '5050:5050' + proxy: + ports: + - '80:80' + - '8090:8080' + flower: + ports: + - '5555:5555' + backend: + ports: + - '8888:8888' diff --git a/{{cookiecutter.project_slug}}/docker-compose.dev.volumes.yml b/{{cookiecutter.project_slug}}/docker-compose.dev.volumes.yml new file mode 100644 index 0000000..9756496 --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.dev.volumes.yml @@ -0,0 +1,11 @@ +version: '3.3' +services: + backend: + volumes: + - ./backend/app:/app + celeryworker: + volumes: + - ./backend/app:/app + backend-tests: + volumes: + - ./backend/app:/app diff --git a/{{cookiecutter.project_slug}}/docker-compose.shared.admin.yml b/{{cookiecutter.project_slug}}/docker-compose.shared.admin.yml new file mode 100644 index 0000000..74bcedd --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.shared.admin.yml @@ -0,0 +1,16 @@ +version: '3.3' +services: + pgadmin: + image: dpage/pgadmin4 + depends_on: + - db + env_file: + - env-pgadmin.env + proxy: + image: traefik:v1.7 + volumes: + - /var/run/docker.sock:/var/run/docker.sock + flower: + image: totem/celery-flower-docker + env_file: + - env-flower.env diff --git a/{{cookiecutter.project_slug}}/docker-compose.shared.base-images.yml b/{{cookiecutter.project_slug}}/docker-compose.shared.base-images.yml new file mode 100644 index 0000000..7123eaa --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.shared.base-images.yml @@ -0,0 +1,6 @@ +version: '3.3' +services: + db: + image: postgres:11 + queue: + image: rabbitmq:3 diff --git a/{{cookiecutter.project_slug}}/docker-compose.shared.depends.yml b/{{cookiecutter.project_slug}}/docker-compose.shared.depends.yml new file mode 100644 index 0000000..a3a6977 --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.shared.depends.yml @@ -0,0 +1,9 @@ +version: '3.3' +services: + backend: + depends_on: + - couchbase + celeryworker: + depends_on: + - couchbase + - queue diff --git a/{{cookiecutter.project_slug}}/docker-compose.shared.env.yml b/{{cookiecutter.project_slug}}/docker-compose.shared.env.yml new file mode 100644 index 0000000..ca5d475 --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.shared.env.yml @@ -0,0 +1,20 @@ +version: '3.3' +services: + db: + env_file: + - env-postgres.env + environment: + - PGDATA=/var/lib/postgresql/data/pgdata + backend: + env_file: + - env-postgres.env + - env-backend.env + environment: + - SERVER_NAME=${DOMAIN} + - SERVER_HOST=https://${DOMAIN} + celeryworker: + env_file: + - env-postgres.env + - env-backend.env + environment: + - SERVER_HOST=https://${DOMAIN} diff --git a/{{cookiecutter.project_slug}}/docker-compose.test.yml b/{{cookiecutter.project_slug}}/docker-compose.test.yml new file mode 100644 index 0000000..69f7c6c --- /dev/null +++ b/{{cookiecutter.project_slug}}/docker-compose.test.yml @@ -0,0 +1,17 @@ +version: '3.3' +services: + backend-tests: + build: + context: ./backend + dockerfile: tests.dockerfile + command: bash -c "while true; do sleep 1; done" + env_file: + - env-couchbase.env + - env-sync-gateway.env + - env-backend.env + environment: + - SERVER_NAME=backend + backend: + environment: + # Don't send emails during testing + - SMTP_HOST= diff --git a/{{cookiecutter.project_slug}}/env-backend.env b/{{cookiecutter.project_slug}}/env-backend.env new file mode 100644 index 0000000..1cf2174 --- /dev/null +++ b/{{cookiecutter.project_slug}}/env-backend.env @@ -0,0 +1,15 @@ +BACKEND_CORS_ORIGINS={{cookiecutter.backend_cors_origins}} +PROJECT_NAME={{cookiecutter.project_name}} +SECRET_KEY={{cookiecutter.secret_key}} +FIRST_SUPERUSER={{cookiecutter.first_superuser}} +FIRST_SUPERUSER_PASSWORD={{cookiecutter.first_superuser_password}} +SMTP_TLS=True +SMTP_PORT={{cookiecutter.smtp_port}} +SMTP_HOST={{cookiecutter.smtp_host}} +SMTP_USER={{cookiecutter.smtp_user}} +SMTP_PASSWORD={{cookiecutter.smtp_password}} +EMAILS_FROM_EMAIL={{cookiecutter.smtp_emails_from_email}} + +USERS_OPEN_REGISTRATION=False + +SENTRY_DSN={{cookiecutter.sentry_dsn}} diff --git a/{{cookiecutter.project_slug}}/env-flower.env b/{{cookiecutter.project_slug}}/env-flower.env new file mode 100644 index 0000000..f1bb0b8 --- /dev/null +++ b/{{cookiecutter.project_slug}}/env-flower.env @@ -0,0 +1,3 @@ +FLOWER_BASIC_AUTH={{cookiecutter.flower_auth}} +AMQP_ADMIN_HOST=queue +AMQP_HOST=queue diff --git a/{{cookiecutter.project_slug}}/env-pgadmin.env b/{{cookiecutter.project_slug}}/env-pgadmin.env new file mode 100644 index 0000000..296cbe8 --- /dev/null +++ b/{{cookiecutter.project_slug}}/env-pgadmin.env @@ -0,0 +1,3 @@ +PGADMIN_LISTEN_PORT=5050 +PGADMIN_DEFAULT_EMAIL={{cookiecutter.pgadmin_default_user}} +PGADMIN_DEFAULT_PASSWORD={{cookiecutter.pgadmin_default_user_password}} diff --git a/{{cookiecutter.project_slug}}/env-postgres.env b/{{cookiecutter.project_slug}}/env-postgres.env new file mode 100644 index 0000000..6971973 --- /dev/null +++ b/{{cookiecutter.project_slug}}/env-postgres.env @@ -0,0 +1,4 @@ +POSTGRES_SERVER=db +POSTGRES_USER=postgres +POSTGRES_PASSWORD={{cookiecutter.postgres_password}} +POSTGRES_DB=app diff --git a/{{cookiecutter.project_slug}}/frontend/.dockerignore b/{{cookiecutter.project_slug}}/frontend/.dockerignore new file mode 100755 index 0000000..3c3629e --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/.dockerignore @@ -0,0 +1 @@ +node_modules diff --git a/{{cookiecutter.project_slug}}/frontend/.env b/{{cookiecutter.project_slug}}/frontend/.env new file mode 100644 index 0000000..adaf330 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/.env @@ -0,0 +1,10 @@ +VUE_APP_DOMAIN_DEV=localhost +# VUE_APP_DOMAIN_DEV=local.dockertoolbox.tiangolo.com +# VUE_APP_DOMAIN_DEV=localhost.tiangolo.com +# VUE_APP_DOMAIN_DEV=dev.{{cookiecutter.domain_main}} +VUE_APP_DOMAIN_STAG={{cookiecutter.domain_staging}} +VUE_APP_DOMAIN_PROD={{cookiecutter.domain_main}} +VUE_APP_NAME={{cookiecutter.project_name}} +VUE_APP_ENV=development +# VUE_APP_ENV=staging +# VUE_APP_ENV=production diff --git a/{{cookiecutter.project_slug}}/frontend/.gitignore b/{{cookiecutter.project_slug}}/frontend/.gitignore new file mode 100644 index 0000000..185e663 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/.gitignore @@ -0,0 +1,21 @@ +.DS_Store +node_modules +/dist + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw* diff --git a/{{cookiecutter.project_slug}}/frontend/Dockerfile b/{{cookiecutter.project_slug}}/frontend/Dockerfile new file mode 100644 index 0000000..fb25c36 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/Dockerfile @@ -0,0 +1,27 @@ +# Stage 0, "build-stage", based on Node.js, to build and compile the frontend +FROM tiangolo/node-frontend:10 as build-stage + +WORKDIR /app + +COPY package*.json /app/ + +RUN npm install + +COPY ./ /app/ + +ARG FRONTEND_ENV=production + +ENV VUE_APP_ENV=${FRONTEND_ENV} + +# Comment out the next line to disable tests +RUN npm run test:unit + +RUN npm run build + + +# Stage 1, based on Nginx, to have only the compiled app, ready for production with Nginx +FROM nginx:1.15 + +COPY --from=build-stage /app/dist/ /usr/share/nginx/html + +COPY --from=build-stage /nginx.conf /etc/nginx/conf.d/default.conf diff --git a/{{cookiecutter.project_slug}}/frontend/README.md b/{{cookiecutter.project_slug}}/frontend/README.md new file mode 100644 index 0000000..60e84fb --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/README.md @@ -0,0 +1,31 @@ +# frontend + +## Project setup +``` +npm install +``` + +### Compiles and hot-reloads for development +``` +npm run serve +``` + +### Compiles and minifies for production +``` +npm run build +``` + +### Run your tests +``` +npm run test +``` + +### Lints and fixes files +``` +npm run lint +``` + +### Run your unit tests +``` +npm run test:unit +``` diff --git a/{{cookiecutter.project_slug}}/frontend/babel.config.js b/{{cookiecutter.project_slug}}/frontend/babel.config.js new file mode 100644 index 0000000..932df28 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/babel.config.js @@ -0,0 +1,10 @@ +module.exports = { + "presets": [ + [ + "@vue/app", + { + "useBuiltIns": "entry" + } + ] + ] +} \ No newline at end of file diff --git a/{{cookiecutter.project_slug}}/frontend/package-lock.json b/{{cookiecutter.project_slug}}/frontend/package-lock.json new file mode 100644 index 0000000..a5ae7db --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/package-lock.json @@ -0,0 +1,13888 @@ +{ + "name": "frontend", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/core": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.2.2.tgz", + "integrity": "sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.2.2", + "@babel/helpers": "^7.2.0", + "@babel/parser": "^7.2.2", + "@babel/template": "^7.2.2", + "@babel/traverse": "^7.2.2", + "@babel/types": "^7.2.2", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.10", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.0.tgz", + "integrity": "sha512-dZTwMvTgWfhmibq4V9X+LMf6Bgl7zAodRn9PvcPdhlzFMbvUutx74dbEv7Atz3ToeEpevYEJtAwfxq/bDCzHWg==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0", + "jsesc": "^2.5.1", + "lodash": "^4.17.10", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", + "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", + "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-call-delegate": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz", + "integrity": "sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.0.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.3.0.tgz", + "integrity": "sha512-DUsQNS2CGLZZ7I3W3fvh0YpPDd6BuWJlDl+qmZZpABZHza2ErE3LxtEzLJFHFC1ZwtlAXvHhbFYbtM5o5B0WBw==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.2.3" + } + }, + "@babel/helper-define-map": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz", + "integrity": "sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/types": "^7.0.0", + "lodash": "^4.17.10" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", + "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz", + "integrity": "sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", + "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", + "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-transforms": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.2.2.tgz", + "integrity": "sha512-YRD7I6Wsv+IHuTPkAmAS4HhY0dkPobgLftHp0cRGZSdrRvmZY8rFvae/GVu3bD00qscuvK3WPHB3YdNpBXUqrA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/template": "^7.2.2", + "@babel/types": "^7.2.2", + "lodash": "^4.17.10" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", + "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.0.0.tgz", + "integrity": "sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", + "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-wrap-function": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-replace-supers": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.2.3.tgz", + "integrity": "sha512-GyieIznGUfPXPWu0yLS6U55Mz67AZD9cUk0BfirOWlPrXlBcan9Gz+vHGz+cPfuoweZSnPzPIm67VtQM0OWZbA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/traverse": "^7.2.3", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-simple-access": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", + "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", + "dev": true, + "requires": { + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", + "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-wrap-function": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", + "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.2.0" + } + }, + "@babel/helpers": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.3.1.tgz", + "integrity": "sha512-Q82R3jKsVpUV99mgX50gOPCWwco9Ec5Iln/8Vyu4osNIOQgSrd9RFrQeUvmvddFNoLwMyOUWU+5ckioEKpDoGA==", + "dev": true, + "requires": { + "@babel/template": "^7.1.2", + "@babel/traverse": "^7.1.5", + "@babel/types": "^7.3.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.1.tgz", + "integrity": "sha512-ATz6yX/L8LEnC3dtLQnIx4ydcPxhLcoy9Vl6re00zb2w5lG6itY6Vhnr1KFRPq/FHNsgl/gh2mjNN20f9iJTTA==", + "dev": true + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", + "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0", + "@babel/plugin-syntax-async-generators": "^7.2.0" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.3.0.tgz", + "integrity": "sha512-wNHxLkEKTQ2ay0tnsam2z7fGZUi+05ziDJflEt3AZTP3oXLKHJp9HqhfroB/vdMvt3sda9fAbq7FsG8QPDrZBg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.3.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-proposal-decorators": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.3.0.tgz", + "integrity": "sha512-3W/oCUmsO43FmZIqermmq6TKaRSYhmh/vybPfVFwQWdSb8xwki38uAIvknCRzuyHRuYfCYmJzL9or1v0AffPjg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.3.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-decorators": "^7.2.0" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", + "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-json-strings": "^7.2.0" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.3.1.tgz", + "integrity": "sha512-Nmmv1+3LqxJu/V5jU9vJmxR/KIRWFk2qLHmbB56yRRRFhlaSuOVXscX3gUmhaKgUhzA3otOHVubbIEVYsZ0eZg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.2.0.tgz", + "integrity": "sha512-LvRVYb7kikuOtIoUeWTkOxQEV1kYvL5B6U3iWEGCzPNRus1MzJweFqORTj+0jkxozkTSYNJozPOddxmqdqsRpw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.2.0" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", + "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-decorators": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.2.0.tgz", + "integrity": "sha512-38QdqVoXdHUQfTpZo3rQwqQdWtCn5tMv4uV6r2RMfTqNBuv4ZBhz79SfaQWKTVmxHjeFv/DnXVC/+agHCklYWA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", + "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", + "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz", + "integrity": "sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", + "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", + "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.2.0.tgz", + "integrity": "sha512-CEHzg4g5UraReozI9D4fblBYABs7IM6UerAVG7EJVrTLC5keh00aEuLUT+O40+mJCEzaXkYfTCUKIyeDfMOFFQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", + "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.2.0.tgz", + "integrity": "sha512-vDTgf19ZEV6mx35yiPJe4fS02mPQUUcBNwWQSZFXSzTSbsJFQvHt7DqyS3LK8oOWALFOsJ+8bbqBgkirZteD5Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "lodash": "^4.17.10" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.2.2.tgz", + "integrity": "sha512-gEZvgTy1VtcDOaQty1l10T3jQmJKlNVxLDCs+3rCVPr6nMkODLELxViq5X9l+rfxbie3XrfrMCYYY6eX3aOcOQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-define-map": "^7.1.0", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", + "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.2.0.tgz", + "integrity": "sha512-coVO2Ayv7g0qdDbrNiadE4bU7lvCd9H539m2gMknyVjjMdwF/iCOM7R+E8PkntoqLkltO0rk+3axhpp/0v68VQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.2.0.tgz", + "integrity": "sha512-sKxnyHfizweTgKZf7XsXu/CNupKhzijptfTM+bozonIuyVrLWVUvYjE2bhuSBML8VQeMxq4Mm63Q9qvcvUcciQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.1.3" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz", + "integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", + "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.2.0.tgz", + "integrity": "sha512-Kz7Mt0SsV2tQk6jG5bBv5phVbkd0gd27SgYD4hH1aLMJRchM0dzHaXvrWhVZ+WxAlDoAKZ7Uy3jVTW2mKXQ1WQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.2.0.tgz", + "integrity": "sha512-kWgksow9lHdvBC2Z4mxTsvc7YdY7w/V6B2vy9cTIPtLEE9NhwoWivaxdNM/S37elu5bqlLP/qOY906LukO9lkQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", + "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz", + "integrity": "sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz", + "integrity": "sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.2.0.tgz", + "integrity": "sha512-aYJwpAhoK9a+1+O625WIjvMY11wkB/ok0WClVwmeo3mCjcNRjt+/8gHWrB5i+00mUju0gWsBkQnPpdvQ7PImmQ==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", + "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.3.0.tgz", + "integrity": "sha512-NxIoNVhk9ZxS+9lSoAQ/LM0V2UEvARLttEHUrRDGKFaAxOYQcrkN/nLRE+BbbicCAvZPl7wMP0X60HsHE5DtQw==", + "dev": true, + "requires": { + "regexp-tree": "^0.1.0" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz", + "integrity": "sha512-yin069FYjah+LbqfGeTfzIBODex/e++Yfa0rH0fpfam9uTbuEeEOx5GLGr210ggOV77mVRNoeqSYqeuaqSzVSw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz", + "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.1.0" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.2.0.tgz", + "integrity": "sha512-kB9+hhUidIgUoBQ0MsxMewhzr8i60nMa2KgeJKQWYrqQpqcBYtnpR+JgkadZVZoaEZ/eKu9mclFaVwhRpLNSzA==", + "dev": true, + "requires": { + "@babel/helper-call-delegate": "^7.1.0", + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz", + "integrity": "sha512-sj2qzsEx8KDVv1QuJc/dEfilkg3RRPvPYx/VnKLtItVQRWt1Wqf5eVCOLZm29CiGFfYYsA3VPjfizTCV0S0Dlw==", + "dev": true, + "requires": { + "regenerator-transform": "^0.13.3" + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.2.0.tgz", + "integrity": "sha512-jIgkljDdq4RYDnJyQsiWbdvGeei/0MOTtSHKO/rfbd/mXBxNpdlulMx49L0HQ4pug1fXannxoqCI+fYSle9eSw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "resolve": "^1.8.1", + "semver": "^5.5.1" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", + "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", + "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", + "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz", + "integrity": "sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", + "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz", + "integrity": "sha512-m48Y0lMhrbXEJnVUaYly29jRXbQ3ksxPrS1Tg8t+MHqzXhtBYAvI51euOBaoAlZLPHsieY9XPVMf80a5x0cPcA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.1.3" + } + }, + "@babel/polyfill": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.2.5.tgz", + "integrity": "sha512-8Y/t3MWThtMLYr0YNC/Q76tqN1w30+b0uQMeFUYauG2UGTR19zyUtFrAzT23zNtBxPp+LbE5E/nwV/q/r3y6ug==", + "requires": { + "core-js": "^2.5.7", + "regenerator-runtime": "^0.12.0" + } + }, + "@babel/preset-env": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.3.1.tgz", + "integrity": "sha512-FHKrD6Dxf30e8xgHQO0zJZpUPfVZg+Xwgz5/RdSWCbza9QLNk4Qbp40ctRoqDxml3O8RMzB1DU55SXeDG6PqHQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-async-generator-functions": "^7.2.0", + "@babel/plugin-proposal-json-strings": "^7.2.0", + "@babel/plugin-proposal-object-rest-spread": "^7.3.1", + "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.2.0", + "@babel/plugin-syntax-async-generators": "^7.2.0", + "@babel/plugin-syntax-json-strings": "^7.2.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", + "@babel/plugin-transform-arrow-functions": "^7.2.0", + "@babel/plugin-transform-async-to-generator": "^7.2.0", + "@babel/plugin-transform-block-scoped-functions": "^7.2.0", + "@babel/plugin-transform-block-scoping": "^7.2.0", + "@babel/plugin-transform-classes": "^7.2.0", + "@babel/plugin-transform-computed-properties": "^7.2.0", + "@babel/plugin-transform-destructuring": "^7.2.0", + "@babel/plugin-transform-dotall-regex": "^7.2.0", + "@babel/plugin-transform-duplicate-keys": "^7.2.0", + "@babel/plugin-transform-exponentiation-operator": "^7.2.0", + "@babel/plugin-transform-for-of": "^7.2.0", + "@babel/plugin-transform-function-name": "^7.2.0", + "@babel/plugin-transform-literals": "^7.2.0", + "@babel/plugin-transform-modules-amd": "^7.2.0", + "@babel/plugin-transform-modules-commonjs": "^7.2.0", + "@babel/plugin-transform-modules-systemjs": "^7.2.0", + "@babel/plugin-transform-modules-umd": "^7.2.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.3.0", + "@babel/plugin-transform-new-target": "^7.0.0", + "@babel/plugin-transform-object-super": "^7.2.0", + "@babel/plugin-transform-parameters": "^7.2.0", + "@babel/plugin-transform-regenerator": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.2.0", + "@babel/plugin-transform-spread": "^7.2.0", + "@babel/plugin-transform-sticky-regex": "^7.2.0", + "@babel/plugin-transform-template-literals": "^7.2.0", + "@babel/plugin-transform-typeof-symbol": "^7.2.0", + "@babel/plugin-transform-unicode-regex": "^7.2.0", + "browserslist": "^4.3.4", + "invariant": "^2.2.2", + "js-levenshtein": "^1.1.3", + "semver": "^5.3.0" + } + }, + "@babel/runtime": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.3.1.tgz", + "integrity": "sha512-7jGW8ppV0ant637pIqAcFfQDDH1orEPGJb8aXfUozuCU3QqX7rX4DA8iwrbPrR1hcH0FTTHz47yQnk+bl5xHQA==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.12.0" + } + }, + "@babel/runtime-corejs2": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.3.1.tgz", + "integrity": "sha512-YpO13776h3e6Wy8dl2J8T9Qwlvopr+b4trCEhHE+yek6yIqV8sx6g3KozdHMbXeBpjosbPi+Ii5Z7X9oXFHUKA==", + "dev": true, + "requires": { + "core-js": "^2.5.7", + "regenerator-runtime": "^0.12.0" + } + }, + "@babel/template": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" + } + }, + "@babel/traverse": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", + "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.2.2", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.2.3", + "@babel/types": "^7.2.2", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.10" + } + }, + "@babel/types": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.0.tgz", + "integrity": "sha512-QkFPw68QqWU1/RVPyBe8SO7lXbPfjtqAxRYQKpFpaB8yMq7X2qAqfwK5LKoQufEkSmO5NQ70O6Kc3Afk03RwXw==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.10", + "to-fast-properties": "^2.0.0" + } + }, + "@intervolga/optimize-cssnano-plugin": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@intervolga/optimize-cssnano-plugin/-/optimize-cssnano-plugin-1.0.6.tgz", + "integrity": "sha512-zN69TnSr0viRSU6cEDIcuPcP67QcpQ6uHACg58FiN9PDrU6SLyGW3MR4tiISbYxy1kDWAVPwD+XwQTWE5cigAA==", + "dev": true, + "requires": { + "cssnano": "^4.0.0", + "cssnano-preset-default": "^4.0.0", + "postcss": "^7.0.0" + } + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + } + }, + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true + }, + "@types/jest": { + "version": "23.3.13", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-23.3.13.tgz", + "integrity": "sha512-ePl4l+7dLLmCucIwgQHAgjiepY++qcI6nb8eAwGNkB6OxmTe3Z9rQU3rSpomqu42PCCnlThZbOoxsf+qylJsLA==", + "dev": true + }, + "@types/node": { + "version": "10.12.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.20.tgz", + "integrity": "sha512-9spv6SklidqxevvZyOUGjZVz4QRXGu2dNaLyXIFzFYZW0AGDykzPRIUFJXTlQXyfzAucddwTcGtJNim8zqSOPA==", + "dev": true + }, + "@types/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.1.tgz", + "integrity": "sha512-eqz8c/0kwNi/OEHQfvIuJVLTst3in0e7uTKeuY+WL/zfKn0xVujOTp42bS/vUUokhK5P2BppLd9JXMOMHcgbjA==", + "dev": true + }, + "@types/semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==", + "dev": true + }, + "@types/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=", + "dev": true + }, + "@types/strip-json-comments": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", + "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", + "dev": true + }, + "@types/webpack-env": { + "version": "1.13.7", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.13.7.tgz", + "integrity": "sha512-rzi6fw7hhxPcCoNVsgysHFlKnhYYvVj7AJwdAO0HQNP5vg9sY0DoRRC1pfuCQm94cOa1sab82HGUtdFlWHIhBg==", + "dev": true + }, + "@vue/babel-helper-vue-jsx-merge-props": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0-beta.2.tgz", + "integrity": "sha512-Yj92Q1GcGjjctecBfnBmVqKSlMdyZaVq10hlZB4HSd1DJgu4cWgpEImJSzcJRUCZmas6UigwE7f4IjJuQs+JvQ==", + "dev": true + }, + "@vue/babel-plugin-transform-vue-jsx": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.0.0-beta.2.tgz", + "integrity": "sha512-fvAymRZAPHitomRE+jIipWRj0STXNSMqeOSdOFu9Ffjqg9WGOxSdCjORxexManfZ2y5QDv7gzI1xfgprsK3nlw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0", + "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0-beta.2", + "html-tags": "^2.0.0", + "lodash.kebabcase": "^4.1.1", + "svg-tags": "^1.0.0" + } + }, + "@vue/babel-preset-app": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-3.3.0.tgz", + "integrity": "sha512-ZnuzErAub1hiFp9c/BI94JMEG7AcbS3/nqToJofOYJFspwWerozxefHF3i3owy6KymBQODVetdyI+iZu80b23A==", + "dev": true, + "requires": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-decorators": "^7.1.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "@babel/runtime": "^7.0.0", + "@babel/runtime-corejs2": "^7.2.0", + "@vue/babel-preset-jsx": "^1.0.0-beta.1", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-plugin-dynamic-import-node": "^2.2.0", + "babel-plugin-transform-vue-jsx": "^4.0.1", + "core-js": "^2.6.1" + } + }, + "@vue/babel-preset-jsx": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.0.0-beta.2.tgz", + "integrity": "sha512-nZoAKBR/h6iPMQ66ieQcIdlpPBmqhtUUcgjBS541jIVxSog1rwzrc00jlsuecLonzUMWPU0PabyitsG74vhN1w==", + "dev": true, + "requires": { + "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0-beta.2", + "@vue/babel-plugin-transform-vue-jsx": "^1.0.0-beta.2", + "@vue/babel-sugar-functional-vue": "^1.0.0-beta.2", + "@vue/babel-sugar-inject-h": "^1.0.0-beta.2", + "@vue/babel-sugar-v-model": "^1.0.0-beta.2", + "@vue/babel-sugar-v-on": "^1.0.0-beta.2" + } + }, + "@vue/babel-sugar-functional-vue": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.0.0-beta.2.tgz", + "integrity": "sha512-5qvi4hmExgjtrESDk0vflL69dIxkDAukJcYH9o4663E8Nh12Jpbmr+Ja8WmgkAPtTVhk90UVcVUFCCZLHBmhkQ==", + "dev": true, + "requires": { + "@babel/plugin-syntax-jsx": "^7.2.0" + } + }, + "@vue/babel-sugar-inject-h": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.0.0-beta.2.tgz", + "integrity": "sha512-qGXZ6yE+1trk82xCVJ9j3shsgI+R2ePj3+o8b2Ee7JNaRqQvMfTwpgx5BRlk4q1+CTjvYexdqBS+q4Kg7sSxcg==", + "dev": true, + "requires": { + "@babel/plugin-syntax-jsx": "^7.2.0" + } + }, + "@vue/babel-sugar-v-model": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.0.0-beta.2.tgz", + "integrity": "sha512-63US3IMEtATJzzK2le/Na53Sk2bp3LHfwZ8eMFwbTaz6e2qeV9frBl3ZYaha64ghT4IDSbrDXUmm0J09EAzFfA==", + "dev": true, + "requires": { + "@babel/plugin-syntax-jsx": "^7.2.0", + "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0-beta.2", + "@vue/babel-plugin-transform-vue-jsx": "^1.0.0-beta.2", + "camelcase": "^5.0.0", + "html-tags": "^2.0.0", + "svg-tags": "^1.0.0" + } + }, + "@vue/babel-sugar-v-on": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.0.0-beta.2.tgz", + "integrity": "sha512-XH/m3k11EKdMY0MrTg4+hQv8BFM8juzHT95chYkgxDmvDdVJnSCuf9+mcysEJttWD4PVuUGN7EHoIWsIhC0dRw==", + "dev": true, + "requires": { + "@babel/plugin-syntax-jsx": "^7.2.0", + "@vue/babel-plugin-transform-vue-jsx": "^1.0.0-beta.2", + "camelcase": "^5.0.0" + } + }, + "@vue/cli-overlay": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@vue/cli-overlay/-/cli-overlay-3.3.0.tgz", + "integrity": "sha512-UyfeuX6txu8sRtfhJOJlPgETzU3KjshKY2qAnC34KJKcS+7oIYRpeOo8jMMLjImVE0g6d8Rn3A1GkXjRiKWW6w==", + "dev": true + }, + "@vue/cli-plugin-babel": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-babel/-/cli-plugin-babel-3.3.0.tgz", + "integrity": "sha512-HS5DwLe42fmkDgu4+78zMITNK+WiLoHKHBCCOuoEqjmsvvKaH/ByCGJOHYgTTe0aI+AiTAAkR2sZ2YulAjlvlQ==", + "dev": true, + "requires": { + "@babel/core": "^7.0.0", + "@vue/babel-preset-app": "^3.3.0", + "babel-loader": "^8.0.4" + } + }, + "@vue/cli-plugin-pwa": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-pwa/-/cli-plugin-pwa-3.3.0.tgz", + "integrity": "sha512-UnhKeWmPe0IeNFei0eIeRvXnsTRFNRGDuqHK0M1eEX9GgCQQ4iPFK+0/wneEbsqorgx+c0rqHUL1S/Q8S7DnJg==", + "dev": true, + "requires": { + "@vue/cli-shared-utils": "^3.3.0", + "workbox-webpack-plugin": "^3.6.3" + } + }, + "@vue/cli-plugin-typescript": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-typescript/-/cli-plugin-typescript-3.3.0.tgz", + "integrity": "sha512-JZ+RYMXL27zq3hU/RnJJaVb6OvsQ5M7qTfZEBWnc45oyw/nFBRLkmFYgQztktvxXvlLcTkJeb8I2cTwxZ2BxnA==", + "dev": true, + "requires": { + "@types/webpack-env": "^1.13.6", + "@vue/cli-shared-utils": "^3.3.0", + "fork-ts-checker-webpack-plugin": "^0.5.2", + "globby": "^8.0.1", + "ts-loader": "^5.3.2", + "tslint": "^5.12.0" + } + }, + "@vue/cli-plugin-unit-jest": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-unit-jest/-/cli-plugin-unit-jest-3.3.0.tgz", + "integrity": "sha512-Y/WkrO95vdvjVjeNO1vZRQUAxlZ6ngdgAzvMzCeEaujbRG4b8M6W7ePSAe8C9yfoVcJtbnoHcBv2er31sPwtyQ==", + "dev": true, + "requires": { + "@vue/cli-shared-utils": "^3.3.0", + "babel-jest": "^23.6.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", + "jest": "^23.6.0", + "jest-serializer-vue": "^2.0.2", + "jest-transform-stub": "^1.0.0", + "vue-jest": "^3.0.2" + } + }, + "@vue/cli-service": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@vue/cli-service/-/cli-service-3.3.1.tgz", + "integrity": "sha512-fo8Mt4pi6GBxRywPxM3uPRAIW/SltauYPw9RHA44rHWpq2adb4B8REtkqBGXTrtQPw9zsdiqHr0djkVO/yv9BA==", + "dev": true, + "requires": { + "@intervolga/optimize-cssnano-plugin": "^1.0.5", + "@vue/cli-overlay": "^3.3.0", + "@vue/cli-shared-utils": "^3.3.0", + "@vue/preload-webpack-plugin": "^1.1.0", + "@vue/web-component-wrapper": "^1.2.0", + "acorn": "^6.0.4", + "acorn-walk": "^6.1.1", + "address": "^1.0.3", + "autoprefixer": "^8.6.5", + "cache-loader": "^1.2.5", + "case-sensitive-paths-webpack-plugin": "^2.1.2", + "chalk": "^2.4.1", + "clipboardy": "^1.2.3", + "cliui": "^4.1.0", + "copy-webpack-plugin": "^4.6.0", + "css-loader": "^1.0.1", + "cssnano": "^4.1.8", + "debug": "^4.1.1", + "escape-string-regexp": "^1.0.5", + "file-loader": "^2.0.0", + "friendly-errors-webpack-plugin": "^1.7.0", + "fs-extra": "^7.0.1", + "globby": "^8.0.1", + "hash-sum": "^1.0.2", + "html-webpack-plugin": "^3.2.0", + "launch-editor-middleware": "^2.2.1", + "lodash.defaultsdeep": "^4.6.0", + "lodash.mapvalues": "^4.6.0", + "lodash.transform": "^4.6.0", + "mini-css-extract-plugin": "^0.5.0", + "minimist": "^1.2.0", + "ora": "^3.0.0", + "portfinder": "^1.0.20", + "postcss-loader": "^3.0.0", + "read-pkg": "^4.0.1", + "semver": "^5.6.0", + "slash": "^2.0.0", + "source-map-url": "^0.4.0", + "ssri": "^6.0.1", + "string.prototype.padend": "^3.0.0", + "terser-webpack-plugin": "^1.2.1", + "thread-loader": "^1.2.0", + "url-loader": "^1.1.2", + "vue-loader": "^15.4.2", + "webpack": ">=4 < 4.29", + "webpack-bundle-analyzer": "^3.0.3", + "webpack-chain": "^4.11.0", + "webpack-dev-server": "^3.1.14", + "webpack-merge": "^4.1.5", + "yorkie": "^2.0.0" + }, + "dependencies": { + "acorn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.6.tgz", + "integrity": "sha512-5M3G/A4uBSMIlfJ+h9W125vJvPFH/zirISsW5qfxF5YzEvXJCtolLoQvM5yZft0DvMcUrPGKPOlgEu55I6iUtA==", + "dev": true + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "read-pkg": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", + "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", + "dev": true, + "requires": { + "normalize-package-data": "^2.3.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0" + } + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + } + } + }, + "@vue/cli-shared-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@vue/cli-shared-utils/-/cli-shared-utils-3.3.0.tgz", + "integrity": "sha512-V/sU1jc7/jMCAbU8uA5f4j9Yd8lTqdi3I6FEHfLG1nstwhaNi4BU3WKWOAl72NYVWFYG8VuCrYWDn75kMimtuw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "execa": "^1.0.0", + "joi": "^14.3.0", + "launch-editor": "^2.2.1", + "lru-cache": "^5.1.1", + "node-ipc": "^9.1.1", + "opn": "^5.3.0", + "ora": "^3.0.0", + "request": "^2.87.0", + "request-promise-native": "^1.0.5", + "semver": "^5.5.0", + "string.prototype.padstart": "^3.0.0" + } + }, + "@vue/component-compiler-utils": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-2.5.1.tgz", + "integrity": "sha512-4mLLh8LYDciX4BO6FVfPbuG3QNYOI70dfsNcdCzHDnN/QYiJ9KWWrf9crSDa9D/aon+QME39Lj+XDHiy9t3sRQ==", + "dev": true, + "requires": { + "consolidate": "^0.15.1", + "hash-sum": "^1.0.2", + "lru-cache": "^4.1.2", + "merge-source-map": "^1.1.0", + "postcss": "^7.0.7", + "postcss-selector-parser": "^5.0.0", + "prettier": "1.16.0", + "source-map": "^0.7.3", + "vue-template-es2015-compiler": "^1.6.0" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } + }, + "@vue/preload-webpack-plugin": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.0.tgz", + "integrity": "sha512-rcn2KhSHESBFMPj5vc5X2pI9bcBNQQixvJXhD5gZ4rN2iym/uH2qfDSQfUS5+qwiz0a85TCkeUs6w6jxFDudbw==", + "dev": true + }, + "@vue/test-utils": { + "version": "1.0.0-beta.28", + "resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-1.0.0-beta.28.tgz", + "integrity": "sha512-uVbFJG0g/H9hf2pgWUdhvQYItRGzQ44cMFf00wp0YEo85pxuvM9e3mx8QLQfx6R2CogxbK4CvV7qvkLblehXeQ==", + "dev": true, + "requires": { + "dom-event-types": "^1.0.0", + "lodash": "^4.17.4" + } + }, + "@vue/web-component-wrapper": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@vue/web-component-wrapper/-/web-component-wrapper-1.2.0.tgz", + "integrity": "sha512-Xn/+vdm9CjuC9p3Ae+lTClNutrVhsXpzxvoTXXtoys6kVRX9FkueSUAqSWAyZntmVLlR4DosBV4pH8y5Z/HbUw==", + "dev": true + }, + "@webassemblyjs/ast": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", + "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/wast-parser": "1.7.11" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", + "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", + "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", + "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", + "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.7.11" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", + "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", + "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", + "dev": true + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", + "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", + "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-buffer": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/wasm-gen": "1.7.11" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", + "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", + "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.1" + } + }, + "@webassemblyjs/utf8": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", + "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", + "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-buffer": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/helper-wasm-section": "1.7.11", + "@webassemblyjs/wasm-gen": "1.7.11", + "@webassemblyjs/wasm-opt": "1.7.11", + "@webassemblyjs/wasm-parser": "1.7.11", + "@webassemblyjs/wast-printer": "1.7.11" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", + "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/ieee754": "1.7.11", + "@webassemblyjs/leb128": "1.7.11", + "@webassemblyjs/utf8": "1.7.11" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", + "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-buffer": "1.7.11", + "@webassemblyjs/wasm-gen": "1.7.11", + "@webassemblyjs/wasm-parser": "1.7.11" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", + "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-api-error": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/ieee754": "1.7.11", + "@webassemblyjs/leb128": "1.7.11", + "@webassemblyjs/utf8": "1.7.11" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", + "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/floating-point-hex-parser": "1.7.11", + "@webassemblyjs/helper-api-error": "1.7.11", + "@webassemblyjs/helper-code-frame": "1.7.11", + "@webassemblyjs/helper-fsm": "1.7.11", + "@xtuc/long": "4.2.1" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", + "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/wast-parser": "1.7.11", + "@xtuc/long": "4.2.1" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", + "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", + "dev": true + }, + "abab": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz", + "integrity": "sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "dev": true, + "requires": { + "mime-types": "~2.1.18", + "negotiator": "0.6.1" + } + }, + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", + "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", + "dev": true, + "requires": { + "acorn": "^5.0.0" + } + }, + "acorn-globals": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.0.tgz", + "integrity": "sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw==", + "dev": true, + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.6.tgz", + "integrity": "sha512-5M3G/A4uBSMIlfJ+h9W125vJvPFH/zirISsW5qfxF5YzEvXJCtolLoQvM5yZft0DvMcUrPGKPOlgEu55I6iUtA==", + "dev": true + } + } + }, + "acorn-walk": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "dev": true + }, + "address": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/address/-/address-1.0.3.tgz", + "integrity": "sha512-z55ocwKBRLryBs394Sm3ushTtBeg6VAeuku7utSoSnsJKvKcnXFIyC6vh27n3rXyxSgkJBBCAvyOn7gSUcTYjg==", + "dev": true + }, + "ajv": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", + "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, + "ajv-keywords": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.3.0.tgz", + "integrity": "sha512-CMzN9S62ZOO4sA/mJZIO4S++ZM7KFWzH3PPWkveLhy4OZ9i1/VatgwWMD46w/XbGCBy7Ye0gCk+Za6mmyfKK7g==", + "dev": true + }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true + }, + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "append-transform": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", + "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", + "dev": true, + "requires": { + "default-require-extensions": "^1.0.0" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "arch": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz", + "integrity": "sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, + "array-filter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", + "dev": true + }, + "array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "requires": { + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "autoprefixer": { + "version": "8.6.5", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-8.6.5.tgz", + "integrity": "sha512-PLWJN3Xo/rycNkx+mp8iBDMTm3FeWe4VmYaZDSqL5QQB9sLsQkG5k8n+LNDFnhh9kdq2K+egL/icpctOmDHwig==", + "dev": true, + "requires": { + "browserslist": "^3.2.8", + "caniuse-lite": "^1.0.30000864", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^6.0.23", + "postcss-value-parser": "^3.2.3" + }, + "dependencies": { + "browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + } + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "axios": { + "version": "0.18.0", + "resolved": "http://registry.npmjs.org/axios/-/axios-0.18.0.tgz", + "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=", + "requires": { + "follow-redirects": "^1.3.0", + "is-buffer": "^1.1.5" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "babel-core": { + "version": "7.0.0-bridge.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", + "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", + "dev": true + }, + "babel-extract-comments": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz", + "integrity": "sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==", + "dev": true, + "requires": { + "babylon": "^6.18.0" + } + }, + "babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "dev": true, + "requires": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + }, + "dependencies": { + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + } + } + }, + "babel-helper-vue-jsx-merge-props": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz", + "integrity": "sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg==", + "dev": true + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-jest": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-23.6.0.tgz", + "integrity": "sha512-lqKGG6LYXYu+DQh/slrQ8nxXQkEkhugdXsU6St7GmhVS7Ilc/22ArwqXNJrf0QaOBjZB0360qZMwXqDYQHXaew==", + "dev": true, + "requires": { + "babel-plugin-istanbul": "^4.1.6", + "babel-preset-jest": "^23.2.0" + } + }, + "babel-loader": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.5.tgz", + "integrity": "sha512-NTnHnVRd2JnRqPC0vW+iOQWU5pchDbYXsG2E6DMXEpMfUcQKclF9gmf3G3ZMhzG7IG9ji4coL0cm+FxeWxDpnw==", + "dev": true, + "requires": { + "find-cache-dir": "^2.0.0", + "loader-utils": "^1.0.2", + "mkdirp": "^0.5.1", + "util.promisify": "^1.0.0" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.2.0.tgz", + "integrity": "sha512-fP899ELUnTaBcIzmrW7nniyqqdYWrWuJUyPWHxFa/c7r7hS6KC8FscNfLlBNIoPSc55kYMGEEKjPjJGCLbE1qA==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-istanbul": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz", + "integrity": "sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ==", + "dev": true, + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.13.0", + "find-up": "^2.1.0", + "istanbul-lib-instrument": "^1.10.1", + "test-exclude": "^4.2.1" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + } + } + }, + "babel-plugin-jest-hoist": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.2.0.tgz", + "integrity": "sha1-5h+uBaHKiAGq3uV6bWa4zvr0QWc=", + "dev": true + }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", + "dev": true + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", + "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "dev": true, + "requires": { + "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-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "dev": true, + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-vue-jsx": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-4.0.1.tgz", + "integrity": "sha512-wbOz7ITB5cloLSjKUU1hWn8zhR+Dwah/RZiTiJY/CQliCwhowmzu6m7NEF+y5EJX/blDzGjRtZvC10Vdb3Q7vw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "babel-preset-jest": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz", + "integrity": "sha1-jsegOhOPABoaj7HoETZSvxpV2kY=", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^23.2.0", + "babel-plugin-syntax-object-rest-spread": "^6.13.0" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "dev": true, + "requires": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + }, + "dependencies": { + "babel-core": { + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + } + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + }, + "dependencies": { + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + } + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bfj": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-6.1.1.tgz", + "integrity": "sha512-+GUNvzHR4nRyGybQc2WpNJL4MJazMuvf92ueIyA0bIkPRwhhQu3IfZQ2PSoVPpCBJfmoSdOxu5rnotfFLlvYRQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.1", + "check-types": "^7.3.0", + "hoopy": "^0.1.2", + "tryer": "^1.0.0" + } + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary-extensions": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", + "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", + "dev": true + }, + "bluebird": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", + "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "dev": true, + "requires": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + }, + "dependencies": { + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + } + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-process-hrtime": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", + "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==", + "dev": true + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "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": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "^4.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": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.1.tgz", + "integrity": "sha512-pEBxEXg7JwaakBXjATYw/D1YZh4QUSCX/Mnd/wnqSRPPSi1U39iDhDoKGoBUcraKdxDlrYqJxSI5nNvD+dWP2A==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000929", + "electron-to-chromium": "^1.3.103", + "node-releases": "^1.1.3" + } + }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, + "bser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", + "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, + "cacache": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", + "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "ssri": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz", + "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.1" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "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" + } + }, + "cache-loader": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-1.2.5.tgz", + "integrity": "sha512-enWKEQ4kO3YreDFd7AtVRjtJBmNiqh/X9hVDReu0C4qm8gsGmySkwuWtdc+N5O+vq5FzxL1mIZc30NyXCB7o/Q==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "mkdirp": "^0.5.1", + "neo-async": "^2.5.0", + "schema-utils": "^0.4.2" + } + }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", + "dev": true + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "dev": true, + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "camelcase": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", + "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "dev": true + }, + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "caniuse-lite": { + "version": "1.0.30000933", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000933.tgz", + "integrity": "sha512-d3QXv7eFTU40DSedSP81dV/ajcGSKpT+GW+uhtWmLvQm9bPk0KK++7i1e2NSW/CXGZhWFt2mFbFtCJ5I5bMuVA==", + "dev": true + }, + "capture-exit": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-1.2.0.tgz", + "integrity": "sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28=", + "dev": true, + "requires": { + "rsvp": "^3.3.3" + } + }, + "case-sensitive-paths-webpack-plugin": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.2.0.tgz", + "integrity": "sha512-u5ElzokS8A1pm9vM3/iDgTcI3xqHxuCao94Oz8etI3cf0Tio0p8izkDYbTIn09uP3yUUr6+veaE6IkjnTYS46g==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "check-types": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-7.4.0.tgz", + "integrity": "sha512-YbulWHdfP99UfZ73NcUDlNJhEIDgm9Doq9GhpyXbF+7Aegi3CVV7qqMCKTTqJxlvEvnQBp9IA+dxsGN6xK/nSg==", + "dev": true + }, + "chokidar": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.0", + "braces": "^2.3.0", + "fsevents": "^1.2.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "lodash.debounce": "^4.0.8", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0", + "upath": "^1.0.5" + } + }, + "chownr": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz", + "integrity": "sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "clean-css": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", + "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", + "dev": true, + "requires": { + "source-map": "~0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-spinners": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.3.1.tgz", + "integrity": "sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==", + "dev": true + }, + "cli-table3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", + "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", + "dev": true, + "requires": { + "colors": "^1.1.2", + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + } + }, + "clipboardy": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-1.2.3.tgz", + "integrity": "sha512-2WNImOvCRe6r63Gk9pShfkwXsVtKCroMAevIbiae021mS850UkWPbevxsBz3tnvjZIEGvlwaqCPsw+4ulzNgJA==", + "dev": true, + "requires": { + "arch": "^2.1.0", + "execa": "^0.8.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", + "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", + "dev": true, + "requires": { + "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" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dev": true, + "requires": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.0.tgz", + "integrity": "sha512-CwyopLkuRYO5ei2EpzpIh6LqJMt6Mt+jZhO5VI5f/wJLZriXQE32/SSqzmrh+QB+AZT81Cj8yv+7zwToW8ahZg==", + "dev": true, + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "dev": true, + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colors": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", + "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==", + "dev": true + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + }, + "common-tags": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", + "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "compressible": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz", + "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==", + "dev": true, + "requires": { + "mime-db": ">= 1.36.0 < 2" + } + }, + "compression": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", + "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.14", + "debug": "2.6.9", + "on-headers": "~1.0.1", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "condense-newlines": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/condense-newlines/-/condense-newlines-0.2.1.tgz", + "integrity": "sha1-PemFVTE5R10yUCyDsC9gaE0kxV8=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-whitespace": "^0.3.0", + "kind-of": "^3.0.2" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "config-chain": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", + "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", + "dev": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "^0.1.4" + } + }, + "consolidate": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", + "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==", + "dev": true, + "requires": { + "bluebird": "^3.1.1" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", + "dev": true + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "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": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "copy-webpack-plugin": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.6.0.tgz", + "integrity": "sha512-Y+SQCF+0NoWQryez2zXn5J5knmr9z/9qSQt7fbL78u83rxmigOy8X5+BFn8CFSuX+nKT8gpYwJX68ekqtQt6ZA==", + "dev": true, + "requires": { + "cacache": "^10.0.4", + "find-cache-dir": "^1.0.0", + "globby": "^7.1.1", + "is-glob": "^4.0.0", + "loader-utils": "^1.1.0", + "minimatch": "^3.0.4", + "p-limit": "^1.0.0", + "serialize-javascript": "^1.4.0" + }, + "dependencies": { + "find-cache-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", + "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "globby": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", + "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "core-js": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.3.tgz", + "integrity": "sha512-l00tmFFZOBHtYhN4Cz7k32VM7vTn3rE2ANjQDxdEN6zmXZ/xq1jQuutnmHvMG1ZJ7xd72+TA5YpUK8wz3rWsfQ==" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cosmiconfig": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.0.7.tgz", + "integrity": "sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.9.0", + "parse-json": "^4.0.0" + }, + "dependencies": { + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + } + } + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "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": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "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" + } + }, + "css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true + }, + "css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "dev": true, + "requires": { + "postcss": "^7.0.1", + "timsort": "^0.3.0" + } + }, + "css-loader": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-1.0.1.tgz", + "integrity": "sha512-+ZHAZm/yqvJ2kDtPne3uX0C+Vr3Zn5jFn2N4HywtS5ujwvsVkyg0VArEXpl3BgczDA8anieki1FIzhchX4yrDw==", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "css-selector-tokenizer": "^0.7.0", + "icss-utils": "^2.1.0", + "loader-utils": "^1.0.2", + "lodash": "^4.17.11", + "postcss": "^6.0.23", + "postcss-modules-extract-imports": "^1.2.0", + "postcss-modules-local-by-default": "^1.2.0", + "postcss-modules-scope": "^1.1.0", + "postcss-modules-values": "^1.3.0", + "postcss-value-parser": "^3.3.0", + "source-list-map": "^2.0.0" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "css-select": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz", + "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^2.1.2", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "dev": true + }, + "css-selector-tokenizer": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz", + "integrity": "sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==", + "dev": true, + "requires": { + "cssesc": "^0.1.0", + "fastparse": "^1.1.1", + "regexpu-core": "^1.0.0" + }, + "dependencies": { + "cssesc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", + "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=", + "dev": true + }, + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + }, + "regexpu-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", + "dev": true, + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + } + } + } + }, + "css-tree": { + "version": "1.0.0-alpha.28", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.28.tgz", + "integrity": "sha512-joNNW1gCp3qFFzj4St6zk+Wh/NBv0vM5YbEreZk0SD4S23S+1xBKb6cLDg2uj4P4k/GUMlIm6cKIDqIG+vdt0w==", + "dev": true, + "requires": { + "mdn-data": "~1.1.0", + "source-map": "^0.5.3" + } + }, + "css-unit-converter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz", + "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=", + "dev": true + }, + "css-url-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/css-url-regex/-/css-url-regex-1.1.0.tgz", + "integrity": "sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w=", + "dev": true + }, + "css-what": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.2.tgz", + "integrity": "sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ==", + "dev": true + }, + "cssesc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", + "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", + "dev": true + }, + "cssnano": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.8.tgz", + "integrity": "sha512-5GIY0VzAHORpbKiL3rMXp4w4M1Ki+XlXgEXyuWXVd3h6hlASb+9Vo76dNP56/elLMVBBsUfusCo1q56uW0UWig==", + "dev": true, + "requires": { + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.6", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "cssnano-preset-default": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.6.tgz", + "integrity": "sha512-UPboYbFaJFtDUhJ4fqctThWbbyF4q01/7UhsZbLzp35l+nUxtzh1SifoVlEfyLM3n3Z0htd8B1YlCxy9i+bQvg==", + "dev": true, + "requires": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.0", + "postcss-colormin": "^4.0.2", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.1", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.10", + "postcss-merge-rules": "^4.0.2", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.1", + "postcss-minify-params": "^4.0.1", + "postcss-minify-selectors": "^4.0.1", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.1", + "postcss-normalize-positions": "^4.0.1", + "postcss-normalize-repeat-style": "^4.0.1", + "postcss-normalize-string": "^4.0.1", + "postcss-normalize-timing-functions": "^4.0.1", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.1", + "postcss-ordered-values": "^4.1.1", + "postcss-reduce-initial": "^4.0.2", + "postcss-reduce-transforms": "^4.0.1", + "postcss-svgo": "^4.0.1", + "postcss-unique-selectors": "^4.0.1" + } + }, + "cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", + "dev": true + }, + "cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", + "dev": true + }, + "cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", + "dev": true + }, + "csso": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/csso/-/csso-3.5.1.tgz", + "integrity": "sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg==", + "dev": true, + "requires": { + "css-tree": "1.0.0-alpha.29" + }, + "dependencies": { + "css-tree": { + "version": "1.0.0-alpha.29", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.29.tgz", + "integrity": "sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==", + "dev": true, + "requires": { + "mdn-data": "~1.1.0", + "source-map": "^0.5.3" + } + } + } + }, + "cssom": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.4.tgz", + "integrity": "sha512-+7prCSORpXNeR4/fUP3rL+TzqtiFfhMvTd7uEqMdgPvLPt4+uzFUeufx5RHjGTACCargg/DiEt/moMQmvnfkog==", + "dev": true + }, + "cssstyle": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.1.1.tgz", + "integrity": "sha512-364AI1l/M5TYcFH83JnOH/pSqgaNnKmYgKrm0didZMGKWjQB60dymwWy1rKUgL3J1ffdq9xVi2yGLHdSjjSNog==", + "dev": true, + "requires": { + "cssom": "0.3.x" + } + }, + "cyclist": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", + "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + }, + "dependencies": { + "whatwg-url": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", + "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + } + } + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "deepmerge": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz", + "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==", + "dev": true + }, + "default-gateway": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-2.7.2.tgz", + "integrity": "sha512-lAc4i9QJR0YHSDFdzeBQKfZ1SRDG3hsJNEkrpcZa8QhBfidLAilT60BDEIVUUGqosFp425KOgB3uYqcnQrWafQ==", + "dev": true, + "requires": { + "execa": "^0.10.0", + "ip-regex": "^2.1.0" + }, + "dependencies": { + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + } + } + }, + "default-require-extensions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", + "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", + "dev": true, + "requires": { + "strip-bom": "^2.0.0" + } + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "del": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", + "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", + "dev": true, + "requires": { + "globby": "^6.1.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "p-map": "^1.1.1", + "pify": "^3.0.0", + "rimraf": "^2.2.8" + }, + "dependencies": { + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", + "dev": true + }, + "detect-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "dev": true + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "dir-glob": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", + "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "path-type": "^3.0.0" + } + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", + "dev": true + }, + "dns-packet": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", + "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "dev": true, + "requires": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "dev": true, + "requires": { + "buffer-indexof": "^1.0.0" + } + }, + "dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dev": true, + "requires": { + "utila": "~0.4" + } + }, + "dom-event-types": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dom-event-types/-/dom-event-types-1.0.0.tgz", + "integrity": "sha512-2G2Vwi2zXTHBGqXHsJ4+ak/iP0N8Ar+G8a7LiD2oup5o4sQWytwqqrZu/O6hIMV0KMID2PL69OhpshLO0n7UJQ==", + "dev": true + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "dev": true, + "requires": { + "domelementtype": "~1.1.1", + "entities": "~1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", + "dev": true + } + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "domhandler": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz", + "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true + }, + "duplexify": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.1.tgz", + "integrity": "sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "easy-stack": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.0.tgz", + "integrity": "sha1-EskbMIWjfwuqM26UhurEv5Tj54g=", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "editorconfig": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.2.tgz", + "integrity": "sha512-GWjSI19PVJAM9IZRGOS+YKI8LN+/sjkSjNyvxL5ucqP9/IqtYNXBaQ/6c/hkPNYQHyOHra2KoXZI/JVpuqwmcQ==", + "dev": true, + "requires": { + "@types/node": "^10.11.7", + "@types/semver": "^5.5.0", + "commander": "^2.19.0", + "lru-cache": "^4.1.3", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "ejs": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz", + "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.109", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.109.tgz", + "integrity": "sha512-1qhgVZD9KIULMyeBkbjU/dWmm30zpPUfdWZfVO3nPhbtqMHJqHr4Ua5wBcWtAymVFrUCuAJxjMF1OhG+bR21Ow==", + "dev": true + }, + "elliptic": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "dev": true, + "requires": { + "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": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "error-stack-parser": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.2.tgz", + "integrity": "sha512-E1fPutRDdIj/hohG0UpT5mayXNCxXP9d+snxFsPU9X0XgccOumKraa3juDMwTUyi7+Bu5+mCGagjg4IYeNbOdw==", + "dev": true, + "requires": { + "stackframe": "^1.0.4" + } + }, + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.0.tgz", + "integrity": "sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==", + "dev": true, + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + } + } + }, + "eslint-scope": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", + "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "event-pubsub": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/event-pubsub/-/event-pubsub-4.3.0.tgz", + "integrity": "sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ==", + "dev": true + }, + "eventemitter3": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", + "dev": true + }, + "events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", + "dev": true + }, + "eventsource": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", + "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "dev": true, + "requires": { + "original": "^1.0.0" + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "exec-sh": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.2.tgz", + "integrity": "sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw==", + "dev": true, + "requires": { + "merge": "^1.2.0" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.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": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "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" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "^2.1.0" + }, + "dependencies": { + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "dev": true, + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "expect": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-23.6.0.tgz", + "integrity": "sha512-dgSoOHgmtn/aDGRVFWclQyPDKl2CQRq0hmIEoUAuQs/2rn2NcvCWcSCovm6BLeuB/7EZuLGu2QfnR+qRt5OM4w==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "jest-diff": "^23.6.0", + "jest-get-type": "^22.1.0", + "jest-matcher-utils": "^23.6.0", + "jest-message-util": "^23.4.0", + "jest-regex-util": "^23.3.0" + } + }, + "express": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", + "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.3", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.4", + "qs": "6.5.2", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.2", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "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" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extract-from-css": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/extract-from-css/-/extract-from-css-0.4.4.tgz", + "integrity": "sha1-HqffLnx8brmSL6COitrqSG9vj5I=", + "dev": true, + "requires": { + "css": "^2.1.0" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-glob": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.6.tgz", + "integrity": "sha512-0BvMaZc1k9F+MeWWMe8pL6YltFzZYcJsYU7D4JyDA6PAczaXvxqQQ/z+mDF7/4Mw01DeUc+i3CTKajnkANkV4w==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + } + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", + "dev": true + }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fb-watchman": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", + "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", + "dev": true, + "requires": { + "bser": "^2.0.0" + } + }, + "figgy-pudding": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", + "dev": true + }, + "file-loader": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-2.0.0.tgz", + "integrity": "sha512-YCsBfd1ZGCyonOKLxPiKPdu+8ld9HAaMEvJewzz+b2eTF7uL5Zm/HdBF6FjCrpCMRq25Mi0U1gl4pwn2TlH7hQ==", + "dev": true, + "requires": { + "loader-utils": "^1.0.2", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "dev": true, + "requires": { + "glob": "^7.0.3", + "minimatch": "^3.0.3" + } + }, + "filesize": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", + "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==", + "dev": true + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "find-babel-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.1.0.tgz", + "integrity": "sha1-rMAQQ6Z0n+w0Qpvmtk9ULrtdY1U=", + "dev": true, + "requires": { + "json5": "^0.5.1", + "path-exists": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + } + } + }, + "find-cache-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.0.0.tgz", + "integrity": "sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "flush-write-stream": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", + "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.4" + } + }, + "follow-redirects": { + "version": "1.5.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.9.tgz", + "integrity": "sha512-Bh65EZI/RU8nx0wbYF9shkFZlqLP+6WT/5FnA3cE/djNSuKNHJEinGGZgu/cQEkeeb2GdFOgenAmn8qaqYke2w==", + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "fork-ts-checker-webpack-plugin": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-0.5.2.tgz", + "integrity": "sha512-a5IG+xXyKnpruI0CP/anyRLAoxWtp3lzdG6flxicANnoSzz64b12dJ7ASAVRrI2OaWwZR2JyBaMHFQqInhWhIw==", + "dev": true, + "requires": { + "babel-code-frame": "^6.22.0", + "chalk": "^2.4.1", + "chokidar": "^2.0.4", + "micromatch": "^3.1.10", + "minimatch": "^3.0.4", + "tapable": "^1.0.0" + } + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "friendly-errors-webpack-plugin": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.7.0.tgz", + "integrity": "sha512-K27M3VK30wVoOarP651zDmb93R9zF28usW4ocaK3mfQeIEI5BPht/EzZs5E8QLLwbLRJQMwscAjDxYPb1FuNiw==", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "error-stack-parser": "^2.0.0", + "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", + "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "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" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "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" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.2.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "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": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz", + "integrity": "sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "^2.0.0" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "dev": true + }, + "globals": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.10.0.tgz", + "integrity": "sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ==", + "dev": true + }, + "globby": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.2.tgz", + "integrity": "sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w==", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "dir-glob": "2.0.0", + "fast-glob": "^2.0.2", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true + }, + "gzip-size": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.0.0.tgz", + "integrity": "sha512-5iI7omclyqrnWw4XbXAmGhPsABkSIDQonv2K0h61lybgofWa6iZyvrI3r2zsJH4P8Nb64fFVzlvfhs0g7BBxAA==", + "dev": true, + "requires": { + "duplexer": "^0.1.1", + "pify": "^3.0.0" + } + }, + "handle-thing": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", + "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==", + "dev": true + }, + "handlebars": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz", + "integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==", + "dev": true, + "requires": { + "async": "^2.5.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", + "dev": true + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoek": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.2.tgz", + "integrity": "sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q==", + "dev": true + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + } + }, + "hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "dev": true + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "dev": true + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", + "dev": true + }, + "hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", + "dev": true + }, + "html-comment-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", + "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", + "dev": true + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, + "html-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", + "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", + "dev": true + }, + "html-minifier": { + "version": "3.5.21", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", + "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", + "dev": true, + "requires": { + "camel-case": "3.0.x", + "clean-css": "4.2.x", + "commander": "2.17.x", + "he": "1.2.x", + "param-case": "2.1.x", + "relateurl": "0.2.x", + "uglify-js": "3.4.x" + }, + "dependencies": { + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + } + } + }, + "html-tags": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", + "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=", + "dev": true + }, + "html-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz", + "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=", + "dev": true, + "requires": { + "html-minifier": "^3.2.3", + "loader-utils": "^0.2.16", + "lodash": "^4.17.3", + "pretty-error": "^2.0.2", + "tapable": "^1.0.0", + "toposort": "^1.0.0", + "util.promisify": "1.0.0" + }, + "dependencies": { + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "dev": true, + "requires": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" + } + } + } + }, + "htmlparser2": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz", + "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=", + "dev": true, + "requires": { + "domelementtype": "1", + "domhandler": "2.1", + "domutils": "1.1", + "readable-stream": "1.0" + }, + "dependencies": { + "domutils": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz", + "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": true + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "http-parser-js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", + "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==", + "dev": true + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "dev": true, + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz", + "integrity": "sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q==", + "dev": true, + "requires": { + "http-proxy": "^1.16.2", + "is-glob": "^4.0.0", + "lodash": "^4.17.5", + "micromatch": "^3.1.9" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", + "dev": true + }, + "icss-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz", + "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", + "dev": true, + "requires": { + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "import-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", + "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", + "dev": true, + "requires": { + "import-from": "^2.1.0" + } + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "import-from": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", + "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "import-local": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz", + "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==", + "dev": true, + "requires": { + "pkg-dir": "^2.0.0", + "resolve-cwd": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "internal-ip": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-3.0.1.tgz", + "integrity": "sha512-NXXgESC2nNVtU+pqmC9e6R8B1GpKxzsAQhffvh5AL79qKnodd+L7tnEQmTiUAVngqLalPbSqRA7XGIEL5nCd0Q==", + "dev": true, + "requires": { + "default-gateway": "^2.6.0", + "ipaddr.js": "^1.5.2" + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "ipaddr.js": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", + "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=", + "dev": true + }, + "is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, + "requires": { + "ci-info": "^1.5.0" + } + }, + "is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", + "dev": true, + "requires": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-generator-fn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz", + "integrity": "sha1-lp1J4bszKfa7fwkIm+JleLLd1Go=", + "dev": true + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dev": true, + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-svg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", + "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", + "dev": true, + "requires": { + "html-comment-regex": "^1.1.0" + } + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-whitespace": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-whitespace/-/is-whitespace-0.3.0.tgz", + "integrity": "sha1-Fjnssb4DauxppUy7QBz77XEUq38=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isemail": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", + "dev": true, + "requires": { + "punycode": "2.x.x" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul-api": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.7.tgz", + "integrity": "sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA==", + "dev": true, + "requires": { + "async": "^2.1.4", + "fileset": "^2.0.2", + "istanbul-lib-coverage": "^1.2.1", + "istanbul-lib-hook": "^1.2.2", + "istanbul-lib-instrument": "^1.10.2", + "istanbul-lib-report": "^1.1.5", + "istanbul-lib-source-maps": "^1.2.6", + "istanbul-reports": "^1.5.1", + "js-yaml": "^3.7.0", + "mkdirp": "^0.5.1", + "once": "^1.4.0" + } + }, + "istanbul-lib-coverage": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz", + "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz", + "integrity": "sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw==", + "dev": true, + "requires": { + "append-transform": "^0.4.0" + } + }, + "istanbul-lib-instrument": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz", + "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==", + "dev": true, + "requires": { + "babel-generator": "^6.18.0", + "babel-template": "^6.16.0", + "babel-traverse": "^6.18.0", + "babel-types": "^6.18.0", + "babylon": "^6.18.0", + "istanbul-lib-coverage": "^1.2.1", + "semver": "^5.3.0" + } + }, + "istanbul-lib-report": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz", + "integrity": "sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^1.2.1", + "mkdirp": "^0.5.1", + "path-parse": "^1.0.5", + "supports-color": "^3.1.2" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz", + "integrity": "sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "istanbul-lib-coverage": "^1.2.1", + "mkdirp": "^0.5.1", + "rimraf": "^2.6.1", + "source-map": "^0.5.3" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "istanbul-reports": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.5.1.tgz", + "integrity": "sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw==", + "dev": true, + "requires": { + "handlebars": "^4.0.3" + } + }, + "javascript-stringify": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-1.6.0.tgz", + "integrity": "sha1-FC0RHzpuPa6PSpr9d9RYVbWpzOM=", + "dev": true + }, + "jest": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-23.6.0.tgz", + "integrity": "sha512-lWzcd+HSiqeuxyhG+EnZds6iO3Y3ZEnMrfZq/OTGvF/C+Z4fPMCdhWTGSAiO2Oym9rbEXfwddHhh6jqrTF3+Lw==", + "dev": true, + "requires": { + "import-local": "^1.0.0", + "jest-cli": "^23.6.0" + }, + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "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" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "jest-cli": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-23.6.0.tgz", + "integrity": "sha512-hgeD1zRUp1E1zsiyOXjEn4LzRLWdJBV//ukAHGlx6s5mfCNJTbhbHjgxnDUXA8fsKWN/HqFFF6X5XcCwC/IvYQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.1.11", + "import-local": "^1.0.0", + "is-ci": "^1.0.10", + "istanbul-api": "^1.3.1", + "istanbul-lib-coverage": "^1.2.0", + "istanbul-lib-instrument": "^1.10.1", + "istanbul-lib-source-maps": "^1.2.4", + "jest-changed-files": "^23.4.2", + "jest-config": "^23.6.0", + "jest-environment-jsdom": "^23.4.0", + "jest-get-type": "^22.1.0", + "jest-haste-map": "^23.6.0", + "jest-message-util": "^23.4.0", + "jest-regex-util": "^23.3.0", + "jest-resolve-dependencies": "^23.6.0", + "jest-runner": "^23.6.0", + "jest-runtime": "^23.6.0", + "jest-snapshot": "^23.6.0", + "jest-util": "^23.4.0", + "jest-validate": "^23.6.0", + "jest-watcher": "^23.4.0", + "jest-worker": "^23.2.0", + "micromatch": "^2.3.11", + "node-notifier": "^5.2.1", + "prompts": "^0.1.9", + "realpath-native": "^1.0.0", + "rimraf": "^2.5.4", + "slash": "^1.0.0", + "string-length": "^2.0.0", + "strip-ansi": "^4.0.0", + "which": "^1.2.12", + "yargs": "^11.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.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" + } + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^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": "^9.0.2" + } + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, + "jest-changed-files": { + "version": "23.4.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-23.4.2.tgz", + "integrity": "sha512-EyNhTAUWEfwnK0Is/09LxoqNDOn7mU7S3EHskG52djOFS/z+IT0jT3h3Ql61+dklcG7bJJitIWEMB4Sp1piHmA==", + "dev": true, + "requires": { + "throat": "^4.0.0" + } + }, + "jest-config": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-23.6.0.tgz", + "integrity": "sha512-i8V7z9BeDXab1+VNo78WM0AtWpBRXJLnkT+lyT+Slx/cbP5sZJ0+NDuLcmBE5hXAoK0aUp7vI+MOxR+R4d8SRQ==", + "dev": true, + "requires": { + "babel-core": "^6.0.0", + "babel-jest": "^23.6.0", + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^23.4.0", + "jest-environment-node": "^23.4.0", + "jest-get-type": "^22.1.0", + "jest-jasmine2": "^23.6.0", + "jest-regex-util": "^23.3.0", + "jest-resolve": "^23.6.0", + "jest-util": "^23.4.0", + "jest-validate": "^23.6.0", + "micromatch": "^2.3.11", + "pretty-format": "^23.6.0" + }, + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "babel-core": { + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.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" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "jest-diff": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-23.6.0.tgz", + "integrity": "sha512-Gz9l5Ov+X3aL5L37IT+8hoCUsof1CVYBb2QEkOupK64XyRR3h+uRpYIm97K7sY8diFxowR8pIGEdyfMKTixo3g==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "diff": "^3.2.0", + "jest-get-type": "^22.1.0", + "pretty-format": "^23.6.0" + } + }, + "jest-docblock": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-23.2.0.tgz", + "integrity": "sha1-8IXh8YVI2Z/dabICB+b9VdkTg6c=", + "dev": true, + "requires": { + "detect-newline": "^2.1.0" + } + }, + "jest-each": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-23.6.0.tgz", + "integrity": "sha512-x7V6M/WGJo6/kLoissORuvLIeAoyo2YqLOoCDkohgJ4XOXSqOtyvr8FbInlAWS77ojBsZrafbozWoKVRdtxFCg==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "pretty-format": "^23.6.0" + } + }, + "jest-environment-jsdom": { + "version": "23.4.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-23.4.0.tgz", + "integrity": "sha1-BWp5UrP+pROsYqFAosNox52eYCM=", + "dev": true, + "requires": { + "jest-mock": "^23.2.0", + "jest-util": "^23.4.0", + "jsdom": "^11.5.1" + } + }, + "jest-environment-node": { + "version": "23.4.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-23.4.0.tgz", + "integrity": "sha1-V+gO0IQd6jAxZ8zozXlSHeuv3hA=", + "dev": true, + "requires": { + "jest-mock": "^23.2.0", + "jest-util": "^23.4.0" + } + }, + "jest-get-type": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-22.4.3.tgz", + "integrity": "sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w==", + "dev": true + }, + "jest-haste-map": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-23.6.0.tgz", + "integrity": "sha512-uyNhMyl6dr6HaXGHp8VF7cK6KpC6G9z9LiMNsst+rJIZ8l7wY0tk8qwjPmEghczojZ2/ZhtEdIabZ0OQRJSGGg==", + "dev": true, + "requires": { + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.1.11", + "invariant": "^2.2.4", + "jest-docblock": "^23.2.0", + "jest-serializer": "^23.0.1", + "jest-worker": "^23.2.0", + "micromatch": "^2.3.11", + "sane": "^2.0.0" + }, + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.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" + } + } + } + }, + "jest-jasmine2": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-23.6.0.tgz", + "integrity": "sha512-pe2Ytgs1nyCs8IvsEJRiRTPC0eVYd8L/dXJGU08GFuBwZ4sYH/lmFDdOL3ZmvJR8QKqV9MFuwlsAi/EWkFUbsQ==", + "dev": true, + "requires": { + "babel-traverse": "^6.0.0", + "chalk": "^2.0.1", + "co": "^4.6.0", + "expect": "^23.6.0", + "is-generator-fn": "^1.0.0", + "jest-diff": "^23.6.0", + "jest-each": "^23.6.0", + "jest-matcher-utils": "^23.6.0", + "jest-message-util": "^23.4.0", + "jest-snapshot": "^23.6.0", + "jest-util": "^23.4.0", + "pretty-format": "^23.6.0" + } + }, + "jest-leak-detector": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-23.6.0.tgz", + "integrity": "sha512-f/8zA04rsl1Nzj10HIyEsXvYlMpMPcy0QkQilVZDFOaPbv2ur71X5u2+C4ZQJGyV/xvVXtCCZ3wQ99IgQxftCg==", + "dev": true, + "requires": { + "pretty-format": "^23.6.0" + } + }, + "jest-matcher-utils": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-23.6.0.tgz", + "integrity": "sha512-rosyCHQfBcol4NsckTn01cdelzWLU9Cq7aaigDf8VwwpIRvWE/9zLgX2bON+FkEW69/0UuYslUe22SOdEf2nog==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-get-type": "^22.1.0", + "pretty-format": "^23.6.0" + } + }, + "jest-message-util": { + "version": "23.4.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-23.4.0.tgz", + "integrity": "sha1-F2EMUJQjSVCNAaPR4L2iwHkIap8=", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0-beta.35", + "chalk": "^2.0.1", + "micromatch": "^2.3.11", + "slash": "^1.0.0", + "stack-utils": "^1.0.1" + }, + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.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" + } + } + } + }, + "jest-mock": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-23.2.0.tgz", + "integrity": "sha1-rRxg8p6HGdR8JuETgJi20YsmETQ=", + "dev": true + }, + "jest-regex-util": { + "version": "23.3.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-23.3.0.tgz", + "integrity": "sha1-X4ZylUfCeFxAAs6qj4Sf6MpHG8U=", + "dev": true + }, + "jest-resolve": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-23.6.0.tgz", + "integrity": "sha512-XyoRxNtO7YGpQDmtQCmZjum1MljDqUCob7XlZ6jy9gsMugHdN2hY4+Acz9Qvjz2mSsOnPSH7skBmDYCHXVZqkA==", + "dev": true, + "requires": { + "browser-resolve": "^1.11.3", + "chalk": "^2.0.1", + "realpath-native": "^1.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-23.6.0.tgz", + "integrity": "sha512-EkQWkFWjGKwRtRyIwRwI6rtPAEyPWlUC2MpzHissYnzJeHcyCn1Hc8j7Nn1xUVrS5C6W5+ZL37XTem4D4pLZdA==", + "dev": true, + "requires": { + "jest-regex-util": "^23.3.0", + "jest-snapshot": "^23.6.0" + } + }, + "jest-runner": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-23.6.0.tgz", + "integrity": "sha512-kw0+uj710dzSJKU6ygri851CObtCD9cN8aNkg8jWJf4ewFyEa6kwmiH/r/M1Ec5IL/6VFa0wnAk6w+gzUtjJzA==", + "dev": true, + "requires": { + "exit": "^0.1.2", + "graceful-fs": "^4.1.11", + "jest-config": "^23.6.0", + "jest-docblock": "^23.2.0", + "jest-haste-map": "^23.6.0", + "jest-jasmine2": "^23.6.0", + "jest-leak-detector": "^23.6.0", + "jest-message-util": "^23.4.0", + "jest-runtime": "^23.6.0", + "jest-util": "^23.4.0", + "jest-worker": "^23.2.0", + "source-map-support": "^0.5.6", + "throat": "^4.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + } + } + }, + "jest-runtime": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-23.6.0.tgz", + "integrity": "sha512-ycnLTNPT2Gv+TRhnAYAQ0B3SryEXhhRj1kA6hBPSeZaNQkJ7GbZsxOLUkwg6YmvWGdX3BB3PYKFLDQCAE1zNOw==", + "dev": true, + "requires": { + "babel-core": "^6.0.0", + "babel-plugin-istanbul": "^4.1.6", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "exit": "^0.1.2", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.11", + "jest-config": "^23.6.0", + "jest-haste-map": "^23.6.0", + "jest-message-util": "^23.4.0", + "jest-regex-util": "^23.3.0", + "jest-resolve": "^23.6.0", + "jest-snapshot": "^23.6.0", + "jest-util": "^23.4.0", + "jest-validate": "^23.6.0", + "micromatch": "^2.3.11", + "realpath-native": "^1.0.0", + "slash": "^1.0.0", + "strip-bom": "3.0.0", + "write-file-atomic": "^2.1.0", + "yargs": "^11.0.0" + }, + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "babel-core": { + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "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" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.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" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^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": "^9.0.2" + } + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, + "jest-serializer": { + "version": "23.0.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-23.0.1.tgz", + "integrity": "sha1-o3dq6zEekP6D+rnlM+hRAr0WQWU=", + "dev": true + }, + "jest-serializer-vue": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jest-serializer-vue/-/jest-serializer-vue-2.0.2.tgz", + "integrity": "sha1-sjjvKGNX7GtIBCG9RxRQUJh9WbM=", + "dev": true, + "requires": { + "pretty": "2.0.0" + } + }, + "jest-snapshot": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-23.6.0.tgz", + "integrity": "sha512-tM7/Bprftun6Cvj2Awh/ikS7zV3pVwjRYU2qNYS51VZHgaAMBs5l4o/69AiDHhQrj5+LA2Lq4VIvK7zYk/bswg==", + "dev": true, + "requires": { + "babel-types": "^6.0.0", + "chalk": "^2.0.1", + "jest-diff": "^23.6.0", + "jest-matcher-utils": "^23.6.0", + "jest-message-util": "^23.4.0", + "jest-resolve": "^23.6.0", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^23.6.0", + "semver": "^5.5.0" + } + }, + "jest-transform-stub": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jest-transform-stub/-/jest-transform-stub-1.0.0.tgz", + "integrity": "sha512-7eilMk4sxi2Fiy223I+BYTS5wJQEGEBqR3D8dy5A6RWmMTnmjipw2ImGDfXzEUBieebyrnitzkJfpNOJSFklLQ==", + "dev": true + }, + "jest-util": { + "version": "23.4.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-23.4.0.tgz", + "integrity": "sha1-TQY8uSe68KI4Mf9hvsLLv0l5NWE=", + "dev": true, + "requires": { + "callsites": "^2.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.11", + "is-ci": "^1.0.10", + "jest-message-util": "^23.4.0", + "mkdirp": "^0.5.1", + "slash": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "jest-validate": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-23.6.0.tgz", + "integrity": "sha512-OFKapYxe72yz7agrDAWi8v2WL8GIfVqcbKRCLbRG9PAxtzF9b1SEDdTpytNDN12z2fJynoBwpMpvj2R39plI2A==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-get-type": "^22.1.0", + "leven": "^2.1.0", + "pretty-format": "^23.6.0" + } + }, + "jest-watcher": { + "version": "23.4.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-23.4.0.tgz", + "integrity": "sha1-0uKM50+NrWxq/JIrksq+9u0FyRw=", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "string-length": "^2.0.0" + } + }, + "jest-worker": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-23.2.0.tgz", + "integrity": "sha1-+vcGqNo2+uYOsmlXJX+ntdjqArk=", + "dev": true, + "requires": { + "merge-stream": "^1.0.1" + } + }, + "joi": { + "version": "14.3.1", + "resolved": "https://registry.npmjs.org/joi/-/joi-14.3.1.tgz", + "integrity": "sha512-LQDdM+pkOrpAn4Lp+neNIFV3axv1Vna3j38bisbQhETPMANYRbFJFUyOZcOClYvM/hppMhGWuKSFEK9vjrB+bQ==", + "dev": true, + "requires": { + "hoek": "6.x.x", + "isemail": "3.x.x", + "topo": "3.x.x" + } + }, + "js-beautify": { + "version": "1.8.9", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.8.9.tgz", + "integrity": "sha512-MwPmLywK9RSX0SPsUJjN7i+RQY9w/yC17Lbrq9ViEefpLRgqAR2BgrMN2AbifkUuhDV8tRauLhLda/9+bE0YQA==", + "dev": true, + "requires": { + "config-chain": "^1.1.12", + "editorconfig": "^0.15.2", + "glob": "^7.1.3", + "mkdirp": "~0.5.0", + "nopt": "~4.0.1" + } + }, + "js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "dev": true + }, + "js-message": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.5.tgz", + "integrity": "sha1-IwDSSxrwjondCVvBpMnJz8uJLRU=", + "dev": true + }, + "js-queue": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/js-queue/-/js-queue-2.0.0.tgz", + "integrity": "sha1-NiITz4YPRo8BJfxslqvBdCUx+Ug=", + "dev": true, + "requires": { + "easy-stack": "^1.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsdom": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", + "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^5.5.3", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": "^1.0.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.1", + "escodegen": "^1.9.1", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.3.0", + "nwsapi": "^2.0.7", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.87.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.4", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.1", + "ws": "^5.2.0", + "xml-name-validator": "^3.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "~0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "dev": true + }, + "json5": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", + "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "kleur": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-2.0.2.tgz", + "integrity": "sha512-77XF9iTllATmG9lSlIv0qdQ2BQ/h9t0bJllHlbvsQ0zUWfU7Yi0S8L5JXzPZgkefIiajLmBJJ4BsMJmqcf7oxQ==", + "dev": true + }, + "launch-editor": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.2.1.tgz", + "integrity": "sha512-On+V7K2uZK6wK7x691ycSUbLD/FyKKelArkbaAMSSJU8JmqmhwN2+mnJDNINuJWSrh2L0kDk+ZQtbC/gOWUwLw==", + "dev": true, + "requires": { + "chalk": "^2.3.0", + "shell-quote": "^1.6.1" + } + }, + "launch-editor-middleware": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/launch-editor-middleware/-/launch-editor-middleware-2.2.1.tgz", + "integrity": "sha512-s0UO2/gEGiCgei3/2UN3SMuUj1phjQN8lcpnvgLSz26fAzNWPQ6Nf/kF5IFClnfU2ehp6LrmKdMU/beveO+2jg==", + "dev": true, + "requires": { + "launch-editor": "^2.2.1" + } + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "left-pad": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", + "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", + "dev": true + }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "lodash.defaultsdeep": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.0.tgz", + "integrity": "sha1-vsECT4WxvZbL6kBbI8FK1kQ6b4E=", + "dev": true + }, + "lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=", + "dev": true + }, + "lodash.mapvalues": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", + "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "lodash.template": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", + "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", + "dev": true, + "requires": { + "lodash._reinterpolate": "~3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", + "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "dev": true, + "requires": { + "lodash._reinterpolate": "~3.0.0" + } + }, + "lodash.transform": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.transform/-/lodash.transform-4.6.0.tgz", + "integrity": "sha1-EjBkIvYzJK7YSD0/ODMrX2cFR6A=", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "loglevel": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz", + "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "math-random": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mdn-data": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz", + "integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "mem": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz", + "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^2.0.0" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "merge": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", + "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==", + "dev": true + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "merge2": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", + "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", + "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", + "dev": true + }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "dev": true + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "dev": true, + "requires": { + "mime-db": "~1.37.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "mini-css-extract-plugin": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz", + "integrity": "sha512-IuaLjruM0vMKhUUT51fQdQzBYTX49dLj8w68ALEAe2A4iYNpIC4eMac67mt3NzycvjOlf07/kYxJDc0RTl1Wqw==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mississippi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz", + "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "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": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dev": true, + "requires": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + } + }, + "multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", + "dev": true + }, + "nan": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", + "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "dev": true + }, + "neo-async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz", + "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "requires": { + "lower-case": "^1.1.1" + } + }, + "node-cache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-4.2.0.tgz", + "integrity": "sha512-obRu6/f7S024ysheAjoYFEEBqqDWv4LOMNJEuO8vMeEw2AT4z+NCzO4hlc2lhI4vATzbCQv6kke9FVdx0RbCOw==", + "dev": true, + "requires": { + "clone": "2.x", + "lodash": "4.x" + }, + "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + } + } + }, + "node-forge": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", + "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-ipc": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-9.1.1.tgz", + "integrity": "sha512-FAyICv0sIRJxVp3GW5fzgaf9jwwRQxAKDJlmNFUL5hOy+W4X/I5AypyHoq0DXXbo9o/gt79gj++4cMr4jVWE/w==", + "dev": true, + "requires": { + "event-pubsub": "4.3.0", + "js-message": "1.0.5", + "js-queue": "2.0.0" + } + }, + "node-libs-browser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz", + "integrity": "sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.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.11.0", + "vm-browserify": "0.0.4" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "node-notifier": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.3.0.tgz", + "integrity": "sha512-AhENzCSGZnZJgBARsUjnQ7DnZbzyP+HxlVXuD0xqAnvL8q+OqtSX7lGg9e8nHzwXkMMXNdVeqq4E2M3EUAqX6Q==", + "dev": true, + "requires": { + "growly": "^1.3.0", + "semver": "^5.5.0", + "shellwords": "^0.1.1", + "which": "^1.3.0" + } + }, + "node-releases": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.6.tgz", + "integrity": "sha512-lODUVHEIZutZx+TDdOk47qLik8FJMXzJ+WnyUGci1MTvTOyzZrz5eVPIIpc5Hb3NfHZGeGHeuwrRYVI1PEITWg==", + "dev": true, + "requires": { + "semver": "^5.3.0" + } + }, + "nopt": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "normalize-package-data": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.2.tgz", + "integrity": "sha512-YcMnjqeoUckXTPKZSAsPjUPLxH85XotbpqK3w4RyCwdFQSU5FxxBys8buehkSfg0j9fKvV1hn7O0+8reEgkAiw==", + "dev": true, + "requires": { + "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": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true + }, + "normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "nwsapi": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.0.9.tgz", + "integrity": "sha512-nlWFSCTYQcHk/6A9FFnfhKc14c3aFhfdNBXgo8Qgi9QTBu/qg3Ww+Uiz9wMzXd1T8GFxPc2QIHB6Qtf2XFryFQ==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "object.values": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", + "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "opener": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", + "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", + "dev": true + }, + "opn": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", + "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "dev": true + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, + "ora": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-3.0.0.tgz", + "integrity": "sha512-LBS97LFe2RV6GJmXBi6OKcETKyklHNMV0xw7BtsVn2MlsgsydyZetSCbCANr+PFLmDyv4KV88nn0eCKza665Mg==", + "dev": true, + "requires": { + "chalk": "^2.3.1", + "cli-cursor": "^2.1.0", + "cli-spinners": "^1.1.0", + "log-symbols": "^2.2.0", + "strip-ansi": "^4.0.0", + "wcwidth": "^1.0.1" + } + }, + "original": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", + "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", + "dev": true, + "requires": { + "url-parse": "^1.4.3" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", + "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", + "dev": true + }, + "p-limit": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", + "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "dev": true + }, + "p-try": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", + "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "dev": true + }, + "pako": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.8.tgz", + "integrity": "sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA==", + "dev": true + }, + "parallel-transform": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", + "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "dev": true, + "requires": { + "cyclist": "~0.2.2", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "dev": true, + "requires": { + "no-case": "^2.2.0" + } + }, + "parse-asn1": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.3.tgz", + "integrity": "sha512-VrPoetlz7B/FqjBLD2f5wBVZvsZVLnRUrxVLfRYhGXCODa/NWE4p3Wp+6+aV3ZPL3KM7/OZmxDIwwijD7yuucg==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "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": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, + "portfinder": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", + "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", + "dev": true, + "requires": { + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "postcss": { + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-calc": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.1.tgz", + "integrity": "sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ==", + "dev": true, + "requires": { + "css-unit-converter": "^1.1.1", + "postcss": "^7.0.5", + "postcss-selector-parser": "^5.0.0-rc.4", + "postcss-value-parser": "^3.3.1" + } + }, + "postcss-colormin": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.2.tgz", + "integrity": "sha512-1QJc2coIehnVFsz0otges8kQLsryi4lo19WD+U5xCWvXd0uw/Z+KKYnbiNDCnO9GP+PvErPHCG0jNvWTngk9Rw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-discard-comments": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.1.tgz", + "integrity": "sha512-Ay+rZu1Sz6g8IdzRjUgG2NafSNpp2MSMOQUb+9kkzzzP+kh07fP0yNbhtFejURnyVXSX3FYy2nVNW1QTnNjgBQ==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-load-config": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.0.0.tgz", + "integrity": "sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ==", + "dev": true, + "requires": { + "cosmiconfig": "^4.0.0", + "import-cwd": "^2.0.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz", + "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==", + "dev": true, + "requires": { + "is-directory": "^0.3.1", + "js-yaml": "^3.9.0", + "parse-json": "^4.0.0", + "require-from-string": "^2.0.1" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + } + } + }, + "postcss-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", + "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "postcss": "^7.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "postcss-merge-longhand": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.10.tgz", + "integrity": "sha512-hME10s6CSjm9nlVIcO1ukR7Jr5RisTaaC1y83jWCivpuBtPohA3pZE7cGTIVSYjXvLnXozHTiVOkG4dnnl756g==", + "dev": true, + "requires": { + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" + } + }, + "postcss-merge-rules": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.2.tgz", + "integrity": "sha512-UiuXwCCJtQy9tAIxsnurfF0mrNHKc4NnNx6NxqmzNNjXpQwLSukUxELHTRF0Rg1pAmcoKLih8PwvZbiordchag==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "dev": true, + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-minify-font-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-minify-gradients": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.1.tgz", + "integrity": "sha512-pySEW3E6Ly5mHm18rekbWiAjVi/Wj8KKt2vwSfVFAWdW6wOIekgqxKxLU7vJfb107o3FDNPkaYFCxGAJBFyogA==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-minify-params": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.1.tgz", + "integrity": "sha512-h4W0FEMEzBLxpxIVelRtMheskOKKp52ND6rJv+nBS33G1twu2tCyurYj/YtgU76+UDCvWeNs0hs8HFAWE2OUFg==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" + } + }, + "postcss-minify-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.1.tgz", + "integrity": "sha512-8+plQkomve3G+CodLCgbhAKrb5lekAnLYuL1d7Nz+/7RANpBEVdgBkPNwljfSKvZ9xkkZTZITd04KP+zeJTJqg==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "dev": true, + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-modules-extract-imports": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz", + "integrity": "sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw==", + "dev": true, + "requires": { + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", + "dev": true, + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", + "dev": true, + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", + "dev": true, + "requires": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "postcss-normalize-charset": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-normalize-display-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.1.tgz", + "integrity": "sha512-R5mC4vaDdvsrku96yXP7zak+O3Mm9Y8IslUobk7IMP+u/g+lXvcN4jngmHY5zeJnrQvE13dfAg5ViU05ZFDwdg==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-positions": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.1.tgz", + "integrity": "sha512-GNoOaLRBM0gvH+ZRb2vKCIujzz4aclli64MBwDuYGU2EY53LwiP7MxOZGE46UGtotrSnmarPPZ69l2S/uxdaWA==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-repeat-style": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.1.tgz", + "integrity": "sha512-fFHPGIjBUyUiswY2rd9rsFcC0t3oRta4wxE1h3lpwfQZwFeFjXFSiDtdJ7APCmHQOnUZnqYBADNRPKPwFAONgA==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-string": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.1.tgz", + "integrity": "sha512-IJoexFTkAvAq5UZVxWXAGE0yLoNN/012v7TQh5nDo6imZJl2Fwgbhy3J2qnIoaDBrtUP0H7JrXlX1jjn2YcvCQ==", + "dev": true, + "requires": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-timing-functions": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.1.tgz", + "integrity": "sha512-1nOtk7ze36+63ONWD8RCaRDYsnzorrj+Q6fxkQV+mlY5+471Qx9kspqv0O/qQNMeApg8KNrRf496zHwJ3tBZ7w==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-unicode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "dev": true, + "requires": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-whitespace": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.1.tgz", + "integrity": "sha512-U8MBODMB2L+nStzOk6VvWWjZgi5kQNShCyjRhMT3s+W9Jw93yIjOnrEkKYD3Ul7ChWbEcjDWmXq0qOL9MIAnAw==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-ordered-values": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.1.tgz", + "integrity": "sha512-PeJiLgJWPzkVF8JuKSBcylaU+hDJ/TX3zqAMIjlghgn1JBi6QwQaDZoDIlqWRcCAI8SxKrt3FCPSRmOgKRB97Q==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-reduce-initial": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.2.tgz", + "integrity": "sha512-epUiC39NonKUKG+P3eAOKKZtm5OtAtQJL7Ye0CBN1f+UQTHzqotudp+hki7zxXm7tT0ZAKDMBj1uihpPjP25ug==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "postcss-reduce-transforms": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.1.tgz", + "integrity": "sha512-sZVr3QlGs0pjh6JAIe6DzWvBaqYw05V1t3d9Tp+VnFRT5j+rsqoWsysh/iSD7YNsULjq9IAylCznIwVd5oU/zA==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-selector-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", + "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", + "dev": true, + "requires": { + "cssesc": "^2.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "postcss-svgo": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.1.tgz", + "integrity": "sha512-YD5uIk5NDRySy0hcI+ZJHwqemv2WiqqzDgtvgMzO8EGSkK5aONyX8HMVFRFJSdO8wUWTuisUFn/d7yRRbBr5Qw==", + "dev": true, + "requires": { + "is-svg": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + } + }, + "postcss-unique-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "prettier": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.0.tgz", + "integrity": "sha512-MCBCYeAuZfejUPdEpkleLWvpRBwLii/Sp5jQs0eb8Ul/drGIDjkL6tAU24tk6yCGf0KPV5rhPPPlczfBmN2pWQ==", + "dev": true + }, + "pretty": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pretty/-/pretty-2.0.0.tgz", + "integrity": "sha1-rbx5YLe7/iiaVX3F9zdhmiINBqU=", + "dev": true, + "requires": { + "condense-newlines": "^0.2.1", + "extend-shallow": "^2.0.1", + "js-beautify": "^1.6.12" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "pretty-bytes": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz", + "integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=", + "dev": true + }, + "pretty-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", + "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "dev": true, + "requires": { + "renderkid": "^2.0.1", + "utila": "~0.4" + } + }, + "pretty-format": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-23.6.0.tgz", + "integrity": "sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0", + "ansi-styles": "^3.2.0" + } + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "prompts": { + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-0.1.14.tgz", + "integrity": "sha512-rxkyiE9YH6zAz/rZpywySLKkpaj0NMVyNw1qhsubdbjjSgcayjTShDreZGlFMcGSu5sab3bAKPfFk78PB90+8w==", + "dev": true, + "requires": { + "kleur": "^2.0.1", + "sisteransi": "^0.1.1" + } + }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", + "dev": true + }, + "proxy-addr": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", + "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", + "dev": true, + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.8.0" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "querystringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.0.tgz", + "integrity": "sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg==", + "dev": true + }, + "randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "dev": true, + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true + } + } + }, + "randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "dev": true + }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "dev": true, + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "dependencies": { + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + } + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "realpath-native": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.0.2.tgz", + "integrity": "sha512-+S3zTvVt9yTntFrBpm7TQmQ3tzpCrnA1a/y+3cUHAc9ZR6aIjG0WNLR+Rj79QpJktY+VeW/TQtFlQ1bzsehI8g==", + "dev": true, + "requires": { + "util.promisify": "^1.0.0" + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz", + "integrity": "sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", + "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==" + }, + "regenerator-transform": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.13.3.tgz", + "integrity": "sha512-5ipTrZFSq5vU2YoGoww4uaRVAK4wyYC4TSICibbfEPOruUu8FFP7ErV0BjmbIOEpn3O/k9na9UEdYR/3m7N6uA==", + "dev": true, + "requires": { + "private": "^0.1.6" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexp-tree": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.1.tgz", + "integrity": "sha512-HwRjOquc9QOwKTgbxvZTcddS5mlNlwePMQ3NFL8broajMLD5CXDAqas8Y5yxJH5QtZp5iRor3YCILd5pz71Cgw==", + "dev": true, + "requires": { + "cli-table3": "^0.5.0", + "colors": "^1.1.2", + "yargs": "^12.0.5" + } + }, + "regexpu-core": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.4.0.tgz", + "integrity": "sha512-eDDWElbwwI3K0Lo6CqbQbA6FwgtCz4kYTarrri1okfkRLZAqstU+B3voZBCjg8Fl6iq0gXrJG6MvRgLthfvgOA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^7.0.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.0.2" + } + }, + "register-service-worker": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/register-service-worker/-/register-service-worker-1.5.2.tgz", + "integrity": "sha512-XNqSZHJsFGnvEGkg/2IrCp6G8Ya3qLj4mq0bSHil/dfdO82LOxGnMnJjAD9MYCvf/8cDCO8pL+1i65yzmP7rPQ==" + }, + "regjsgen": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", + "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", + "dev": true + }, + "regjsparser": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", + "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "dev": true + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "renderkid": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.2.tgz", + "integrity": "sha512-FsygIxevi1jSiPY9h7vZmBFUbAOcbYm9UwyiLNdVsLRs/5We9Ob5NMPbGYUTWiLq5L+ezlVdE0A8bbME5CWTpg==", + "dev": true, + "requires": { + "css-select": "^1.1.0", + "dom-converter": "~0.2", + "htmlparser2": "~3.3.0", + "strip-ansi": "^3.0.0", + "utila": "^0.4.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "dev": true, + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "request-promise-core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", + "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "dev": true, + "requires": { + "lodash": "^4.13.1" + } + }, + "request-promise-native": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", + "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", + "dev": true, + "requires": { + "request-promise-core": "1.1.1", + "stealthy-require": "^1.1.0", + "tough-cookie": ">=2.3.3" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", + "dev": true + }, + "rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rsvp": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz", + "integrity": "sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==", + "dev": true + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sane": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/sane/-/sane-2.5.2.tgz", + "integrity": "sha1-tNwYYcIbQn6SlQej51HiosuKs/o=", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "capture-exit": "^1.2.0", + "exec-sh": "^0.2.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.3", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5", + "watch": "~0.18.0" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "schema-utils": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", + "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0" + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", + "dev": true + }, + "selfsigned": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz", + "integrity": "sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==", + "dev": true, + "requires": { + "node-forge": "0.7.5" + } + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz", + "integrity": "sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw==", + "dev": true + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shell-quote": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "dev": true, + "requires": { + "array-filter": "~0.0.0", + "array-map": "~0.0.0", + "array-reduce": "~0.0.0", + "jsonify": "~0.0.0" + } + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dev": true, + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true + } + } + }, + "sisteransi": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-0.1.1.tgz", + "integrity": "sha512-PmGOd02bM9YO5ifxpw36nrNMBTptEtfRl4qUYl9SndkolplkrZZOW7PGHjrZL53QvMVj9nQ+TKqUnRsw4tJa4g==", + "dev": true + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "sockjs": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", + "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", + "dev": true, + "requires": { + "faye-websocket": "^0.10.0", + "uuid": "^3.0.1" + } + }, + "sockjs-client": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.3.0.tgz", + "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==", + "dev": true, + "requires": { + "debug": "^3.2.5", + "eventsource": "^1.0.7", + "faye-websocket": "~0.11.1", + "inherits": "^2.0.3", + "json3": "^3.3.2", + "url-parse": "^1.4.3" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "faye-websocket": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", + "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", + "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==", + "dev": true + }, + "spdy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz", + "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + }, + "dependencies": { + "readable-stream": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz", + "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, + "stack-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", + "dev": true + }, + "stackframe": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.0.4.tgz", + "integrity": "sha512-to7oADIniaYwS3MhtCa/sQhrxidCCQiF/qp4/m5iN3ipf0Y7Xlri0f6eG29r08aL7JYl8n32AF3Q5GYBZ7K8vw==", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "dev": true + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "dev": true + }, + "string-length": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", + "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", + "dev": true, + "requires": { + "astral-regex": "^1.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string.prototype.padend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz", + "integrity": "sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.4.3", + "function-bind": "^1.0.2" + } + }, + "string.prototype.padstart": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.padstart/-/string.prototype.padstart-3.0.0.tgz", + "integrity": "sha1-W8+tOfRkm7LQMSkuGbzwtRDUskI=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.4.3", + "function-bind": "^1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-comments": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-1.0.2.tgz", + "integrity": "sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw==", + "dev": true, + "requires": { + "babel-extract-comments": "^1.0.0", + "babel-plugin-transform-object-rest-spread": "^6.26.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "stylehacks": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.1.tgz", + "integrity": "sha512-TK5zEPeD9NyC1uPIdjikzsgWxdQQN/ry1X3d1iOz1UkYDCmcr928gWD1KHgyC27F50UnE0xCTrBOO1l6KR8M4w==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "dev": true, + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", + "dev": true + }, + "svgo": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.1.1.tgz", + "integrity": "sha512-GBkJbnTuFpM4jFbiERHDWhZc/S/kpHToqmZag3aEBjPYK44JAN2QBjvrGIxLOoCyMZjuFQIfTO2eJd8uwLY/9g==", + "dev": true, + "requires": { + "coa": "~2.0.1", + "colors": "~1.1.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "~0.1.0", + "css-tree": "1.0.0-alpha.28", + "css-url-regex": "^1.1.0", + "csso": "^3.5.0", + "js-yaml": "^3.12.0", + "mkdirp": "~0.5.1", + "object.values": "^1.0.4", + "sax": "~1.2.4", + "stable": "~0.1.6", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "dependencies": { + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + } + } + }, + "symbol-tree": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", + "dev": true + }, + "tapable": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.1.tgz", + "integrity": "sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA==", + "dev": true + }, + "terser": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-3.14.1.tgz", + "integrity": "sha512-NSo3E99QDbYSMeJaEk9YW2lTg3qS9V0aKGlb+PlOrei1X02r1wSBHCNX/O+yeTRFSWPKPIGj6MqvvdqV4rnVGw==", + "dev": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1", + "source-map-support": "~0.5.6" + }, + "dependencies": { + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + } + } + }, + "terser-webpack-plugin": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.1.tgz", + "integrity": "sha512-GGSt+gbT0oKcMDmPx4SRSfJPE1XaN3kQRWG4ghxKQw9cn5G9x6aCKSsgYdvyM0na9NJ4Drv0RG6jbBByZ5CMjw==", + "dev": true, + "requires": { + "cacache": "^11.0.2", + "find-cache-dir": "^2.0.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^1.4.0", + "source-map": "^0.6.1", + "terser": "^3.8.1", + "webpack-sources": "^1.1.0", + "worker-farm": "^1.5.2" + }, + "dependencies": { + "cacache": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", + "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==", + "dev": true, + "requires": { + "bluebird": "^3.5.3", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.3", + "graceful-fs": "^4.1.15", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.2", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "test-exclude": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.2.3.tgz", + "integrity": "sha512-SYbXgY64PT+4GAL2ocI3HwPa4Q4TBKm0cwAVeKOt/Aoc0gSpNRjJX8w0pA1LMKZ3LBmd8pYBqApFNQLII9kavA==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "micromatch": "^2.3.11", + "object-assign": "^4.1.0", + "read-pkg-up": "^1.0.1", + "require-main-filename": "^1.0.1" + }, + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.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" + } + } + } + }, + "thread-loader": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/thread-loader/-/thread-loader-1.2.0.tgz", + "integrity": "sha512-acJ0rvUk53+ly9cqYWNOpPqOgCkNpmHLPDGduNm4hDQWF7EDKEJXAopG9iEWsPPcml09wePkq3NF+ZUqnO6tbg==", + "dev": true, + "requires": { + "async": "^2.3.0", + "loader-runner": "^2.3.0", + "loader-utils": "^1.1.0" + } + }, + "throat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", + "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "thunky": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz", + "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==", + "dev": true + }, + "timers-browserify": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", + "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", + "dev": true + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "topo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", + "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", + "dev": true, + "requires": { + "hoek": "6.x.x" + } + }, + "toposort": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", + "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", + "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", + "dev": true + }, + "ts-jest": { + "version": "23.10.5", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-23.10.5.tgz", + "integrity": "sha512-MRCs9qnGoyKgFc8adDEntAOP64fWK1vZKnOYU1o2HxaqjdJvGqmkLCPCnVq1/If4zkUmEjKPnCiUisTrlX2p2A==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "json5": "2.x", + "make-error": "1.x", + "mkdirp": "0.x", + "resolve": "1.x", + "semver": "^5.5", + "yargs-parser": "10.x" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, + "ts-loader": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.3.3.tgz", + "integrity": "sha512-KwF1SplmOJepnoZ4eRIloH/zXL195F51skt7reEsS6jvDqzgc/YSbz9b8E07GxIUwLXdcD4ssrJu6v8CwaTafA==", + "dev": true, + "requires": { + "chalk": "^2.3.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.0.2", + "micromatch": "^3.1.4", + "semver": "^5.0.1" + } + }, + "tsconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", + "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==", + "dev": true, + "requires": { + "@types/strip-bom": "^3.0.0", + "@types/strip-json-comments": "0.0.30", + "strip-bom": "^3.0.0", + "strip-json-comments": "^2.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, + "tslint": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.1.tgz", + "integrity": "sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw==", + "dev": true, + "requires": { + "babel-code-frame": "^6.22.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^3.2.0", + "glob": "^7.1.1", + "js-yaml": "^3.7.0", + "minimatch": "^3.0.4", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.27.2" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typesafe-vuex": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/typesafe-vuex/-/typesafe-vuex-3.1.1.tgz", + "integrity": "sha512-eckied4/Ogk/YMqLu2dsySOI5y4julBFMewtqaqSRPHMR3Q/uQWpy2p6llABDG4Y+dM5JOAr9tp8lxQJspriRQ==" + }, + "typescript": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz", + "integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==", + "dev": true + }, + "uglify-js": { + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", + "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", + "dev": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz", + "integrity": "sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz", + "integrity": "sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg==", + "dev": true + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", + "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "upath": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "dev": true + }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-loader": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.2.tgz", + "integrity": "sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "mime": "^2.0.3", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "url-parse": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz", + "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==", + "dev": true, + "requires": { + "querystringify": "^2.0.0", + "requires-port": "^1.0.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "vee-validate": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-2.1.7.tgz", + "integrity": "sha512-IyPDTTvIRY6o9y14jXlgfY76Qv+hmvYDwNaMn9JY5KbQN8a1tJAu7H/+a/+EdHg1w8Zl9tsdG8lndGqY1lyMzQ==" + }, + "vendors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz", + "integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "requires": { + "indexof": "0.0.1" + } + }, + "vue": { + "version": "2.5.22", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.5.22.tgz", + "integrity": "sha512-pxY3ZHlXNJMFQbkjEgGVMaMMkSV1ONpz+4qB55kZuJzyJOhn6MSy/YZdzhdnumegNzVTL/Dn3Pp4UrVBYt1j/g==" + }, + "vue-class-component": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/vue-class-component/-/vue-class-component-6.3.2.tgz", + "integrity": "sha512-cH208IoM+jgZyEf/g7mnFyofwPDJTM/QvBNhYMjqGB8fCsRyTf68rH2ISw/G20tJv+5mIThQ3upKwoL4jLTr1A==" + }, + "vue-cli-plugin-vuetify": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/vue-cli-plugin-vuetify/-/vue-cli-plugin-vuetify-0.2.1.tgz", + "integrity": "sha512-kYnDF8a8TmjF89mxHhBIqZPOizGLEXU3MLetw5kfLeG1NBeyejbdEGaUFy59LETvJFnBKYjN4OYFChlZhlLNLg==", + "dev": true + }, + "vue-hot-reload-api": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.1.tgz", + "integrity": "sha512-AA86yKZ5uOKz87/q1UpngEXhbRkaYg1b7HMMVRobNV1IVKqZe8oLIzo6iMocVwZXnYitlGwf2k4ZRLOZlS8oPQ==", + "dev": true + }, + "vue-jest": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vue-jest/-/vue-jest-3.0.2.tgz", + "integrity": "sha512-5XIQ1xQFW0ZnWxHWM7adVA2IqbDsdw1vhgZfGFX4oWd75J38KIS3YT41PtiE7lpMLmNM6+VJ0uprT2mhHjUgkA==", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0", + "chalk": "^2.1.0", + "extract-from-css": "^0.4.4", + "find-babel-config": "^1.1.0", + "js-beautify": "^1.6.14", + "node-cache": "^4.1.1", + "object-assign": "^4.1.1", + "source-map": "^0.5.6", + "tsconfig": "^7.0.0", + "vue-template-es2015-compiler": "^1.6.0" + } + }, + "vue-loader": { + "version": "15.6.2", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.6.2.tgz", + "integrity": "sha512-T6fONodj861M3PqZ1jlbUFjeezbUnPRY2bd+3eZuDvYADgkN3VFU2H5feqySNg9XBt8rcbyBGmFWTZtrOX+v5w==", + "dev": true, + "requires": { + "@vue/component-compiler-utils": "^2.5.1", + "hash-sum": "^1.0.2", + "loader-utils": "^1.1.0", + "vue-hot-reload-api": "^2.3.0", + "vue-style-loader": "^4.1.0" + } + }, + "vue-property-decorator": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/vue-property-decorator/-/vue-property-decorator-7.3.0.tgz", + "integrity": "sha512-HarXfTQ/Nxm4s/APpAaGIGHq5ZzslApImQy8ZrtkfGamw8rUFAVgMS5C50/AQ80+wfw3Wpnf4bNzbmj75m/k2Q==", + "requires": { + "vue-class-component": "^6.2.0" + } + }, + "vue-router": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.0.2.tgz", + "integrity": "sha512-opKtsxjp9eOcFWdp6xLQPLmRGgfM932Tl56U9chYTnoWqKxQ8M20N7AkdEbM5beUh6wICoFGYugAX9vQjyJLFg==" + }, + "vue-style-loader": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz", + "integrity": "sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ==", + "dev": true, + "requires": { + "hash-sum": "^1.0.2", + "loader-utils": "^1.0.2" + } + }, + "vue-template-compiler": { + "version": "2.5.22", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.5.22.tgz", + "integrity": "sha512-1VTw/NPTUeHNiwhkq6NkFzO7gYLjFCueBN0FX8NEiQIemd5EUMQ5hxrF7O0zCPo5tae+U9S/scETPea+hIz8Eg==", + "dev": true, + "requires": { + "de-indent": "^1.0.2", + "he": "^1.1.0" + } + }, + "vue-template-es2015-compiler": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.8.2.tgz", + "integrity": "sha512-cliV19VHLJqFUYbz/XeWXe5CO6guzwd0yrrqqp0bmjlMP3ZZULY7fu8RTC4+3lmHwo6ESVDHFDsvjB15hcR5IA==", + "dev": true + }, + "vuetify": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-1.4.4.tgz", + "integrity": "sha512-i0fNciTrzP+U6NinB2kmNMC5vWXtrTy5QcVFLOxv4dhhqTiMTyHj7rV1B2lwBTZYoDhimmSAYRfqHeKdCMx+Gg==" + }, + "vuex": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.1.0.tgz", + "integrity": "sha512-mdHeHT/7u4BncpUZMlxNaIdcN/HIt1GsGG5LKByArvYG/v6DvHcOxvDCts+7SRdCoIRGllK8IMZvQtQXLppDYg==" + }, + "w3c-hr-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", + "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "dev": true, + "requires": { + "browser-process-hrtime": "^0.1.2" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, + "watch": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/watch/-/watch-0.18.0.tgz", + "integrity": "sha1-KAlUdsbffJDJYxOJkMClQj60uYY=", + "dev": true, + "requires": { + "exec-sh": "^0.2.0", + "minimist": "^1.2.0" + } + }, + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "dev": true, + "requires": { + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "webpack": { + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.4.tgz", + "integrity": "sha512-NxjD61WsK/a3JIdwWjtIpimmvE6UrRi3yG54/74Hk9rwNj5FPkA4DJCf1z4ByDWLkvZhTZE+P3C/eh6UD5lDcw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-module-context": "1.7.11", + "@webassemblyjs/wasm-edit": "1.7.11", + "@webassemblyjs/wasm-parser": "1.7.11", + "acorn": "^5.6.2", + "acorn-dynamic-import": "^3.0.0", + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0", + "chrome-trace-event": "^1.0.0", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.0", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.3.0", + "loader-utils": "^1.1.0", + "memory-fs": "~0.4.1", + "micromatch": "^3.1.8", + "mkdirp": "~0.5.0", + "neo-async": "^2.5.0", + "node-libs-browser": "^2.0.0", + "schema-utils": "^0.4.4", + "tapable": "^1.1.0", + "terser-webpack-plugin": "^1.1.0", + "watchpack": "^1.5.0", + "webpack-sources": "^1.3.0" + } + }, + "webpack-bundle-analyzer": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.0.3.tgz", + "integrity": "sha512-naLWiRfmtH4UJgtUktRTLw6FdoZJ2RvCR9ePbwM9aRMsS/KjFerkPZG9epEvXRAw5d5oPdrs9+3p+afNjxW8Xw==", + "dev": true, + "requires": { + "acorn": "^5.7.3", + "bfj": "^6.1.1", + "chalk": "^2.4.1", + "commander": "^2.18.0", + "ejs": "^2.6.1", + "express": "^4.16.3", + "filesize": "^3.6.1", + "gzip-size": "^5.0.0", + "lodash": "^4.17.10", + "mkdirp": "^0.5.1", + "opener": "^1.5.1", + "ws": "^6.0.0" + }, + "dependencies": { + "ws": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.3.tgz", + "integrity": "sha512-tbSxiT+qJI223AP4iLfQbkbxkwdFcneYinM2+x46Gx2wgvbaOMO36czfdfVUBRTHvzAMRhDd98sA5d/BuWbQdg==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "webpack-chain": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-4.12.1.tgz", + "integrity": "sha512-BCfKo2YkDe2ByqkEWe1Rw+zko4LsyS75LVr29C6xIrxAg9JHJ4pl8kaIZ396SUSNp6b4815dRZPSTAS8LlURRQ==", + "dev": true, + "requires": { + "deepmerge": "^1.5.2", + "javascript-stringify": "^1.6.0" + } + }, + "webpack-dev-middleware": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.4.0.tgz", + "integrity": "sha512-Q9Iyc0X9dP9bAsYskAVJ/hmIZZQwf/3Sy4xCAZgL5cUkjZmUZLt4l5HpbST/Pdgjn3u6pE7u5OdGd1apgzRujA==", + "dev": true, + "requires": { + "memory-fs": "~0.4.1", + "mime": "^2.3.1", + "range-parser": "^1.0.3", + "webpack-log": "^2.0.0" + } + }, + "webpack-dev-server": { + "version": "3.1.14", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.1.14.tgz", + "integrity": "sha512-mGXDgz5SlTxcF3hUpfC8hrQ11yhAttuUQWf1Wmb+6zo3x6rb7b9mIfuQvAPLdfDRCGRGvakBWHdHOa0I9p/EVQ==", + "dev": true, + "requires": { + "ansi-html": "0.0.7", + "bonjour": "^3.5.0", + "chokidar": "^2.0.0", + "compression": "^1.5.2", + "connect-history-api-fallback": "^1.3.0", + "debug": "^3.1.0", + "del": "^3.0.0", + "express": "^4.16.2", + "html-entities": "^1.2.0", + "http-proxy-middleware": "~0.18.0", + "import-local": "^2.0.0", + "internal-ip": "^3.0.1", + "ip": "^1.1.5", + "killable": "^1.0.0", + "loglevel": "^1.4.1", + "opn": "^5.1.0", + "portfinder": "^1.0.9", + "schema-utils": "^1.0.0", + "selfsigned": "^1.9.1", + "semver": "^5.6.0", + "serve-index": "^1.7.2", + "sockjs": "0.3.19", + "sockjs-client": "1.3.0", + "spdy": "^4.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^5.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "3.4.0", + "webpack-log": "^2.0.0", + "yargs": "12.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-2.0.0.tgz", + "integrity": "sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==", + "dev": true, + "requires": { + "xregexp": "4.0.0" + } + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "yargs": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.2.tgz", + "integrity": "sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^2.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^10.1.0" + } + }, + "yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, + "webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "requires": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + } + }, + "webpack-merge": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.1.tgz", + "integrity": "sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw==", + "dev": true, + "requires": { + "lodash": "^4.17.5" + } + }, + "webpack-sources": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", + "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "websocket-driver": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", + "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "dev": true, + "requires": { + "http-parser-js": ">=0.4.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", + "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + }, + "workbox-background-sync": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-3.6.3.tgz", + "integrity": "sha512-ypLo0B6dces4gSpaslmDg5wuoUWrHHVJfFWwl1udvSylLdXvnrfhFfriCS42SNEe5lsZtcNZF27W/SMzBlva7Q==", + "dev": true, + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-broadcast-cache-update": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-broadcast-cache-update/-/workbox-broadcast-cache-update-3.6.3.tgz", + "integrity": "sha512-pJl4lbClQcvp0SyTiEw0zLSsVYE1RDlCPtpKnpMjxFtu8lCFTAEuVyzxp9w7GF4/b3P4h5nyQ+q7V9mIR7YzGg==", + "dev": true, + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-build": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-3.6.3.tgz", + "integrity": "sha512-w0clZ/pVjL8VXy6GfthefxpEXs0T8uiRuopZSFVQ8ovfbH6c6kUpEh6DcYwm/Y6dyWPiCucdyAZotgjz+nRz8g==", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "common-tags": "^1.4.0", + "fs-extra": "^4.0.2", + "glob": "^7.1.2", + "joi": "^11.1.1", + "lodash.template": "^4.4.0", + "pretty-bytes": "^4.0.2", + "stringify-object": "^3.2.2", + "strip-comments": "^1.0.2", + "workbox-background-sync": "^3.6.3", + "workbox-broadcast-cache-update": "^3.6.3", + "workbox-cache-expiration": "^3.6.3", + "workbox-cacheable-response": "^3.6.3", + "workbox-core": "^3.6.3", + "workbox-google-analytics": "^3.6.3", + "workbox-navigation-preload": "^3.6.3", + "workbox-precaching": "^3.6.3", + "workbox-range-requests": "^3.6.3", + "workbox-routing": "^3.6.3", + "workbox-strategies": "^3.6.3", + "workbox-streams": "^3.6.3", + "workbox-sw": "^3.6.3" + }, + "dependencies": { + "hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "dev": true + }, + "joi": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-11.4.0.tgz", + "integrity": "sha512-O7Uw+w/zEWgbL6OcHbyACKSj0PkQeUgmehdoXVSxt92QFCq4+1390Rwh5moI2K/OgC7D8RHRZqHZxT2husMJHA==", + "dev": true, + "requires": { + "hoek": "4.x.x", + "isemail": "3.x.x", + "topo": "2.x.x" + } + }, + "topo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/topo/-/topo-2.0.2.tgz", + "integrity": "sha1-zVYVdSU5BXwNwEkaYhw7xvvh0YI=", + "dev": true, + "requires": { + "hoek": "4.x.x" + } + } + } + }, + "workbox-cache-expiration": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-cache-expiration/-/workbox-cache-expiration-3.6.3.tgz", + "integrity": "sha512-+ECNph/6doYx89oopO/UolYdDmQtGUgo8KCgluwBF/RieyA1ZOFKfrSiNjztxOrGJoyBB7raTIOlEEwZ1LaHoA==", + "dev": true, + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-cacheable-response": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-3.6.3.tgz", + "integrity": "sha512-QpmbGA9SLcA7fklBLm06C4zFg577Dt8u3QgLM0eMnnbaVv3rhm4vbmDpBkyTqvgK/Ly8MBDQzlXDtUCswQwqqg==", + "dev": true, + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-core": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-3.6.3.tgz", + "integrity": "sha512-cx9cx0nscPkIWs8Pt98HGrS9/aORuUcSkWjG25GqNWdvD/pSe7/5Oh3BKs0fC+rUshCiyLbxW54q0hA+GqZeSQ==", + "dev": true + }, + "workbox-google-analytics": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-3.6.3.tgz", + "integrity": "sha512-RQBUo/6SXtIaQTRFj4RQZ9e1gAl7D8oS5S+Hi173Kk70/BgJjzPwXpC5A249Jv5YfkCOLMQCeF9A27BiD0b0ig==", + "dev": true, + "requires": { + "workbox-background-sync": "^3.6.3", + "workbox-core": "^3.6.3", + "workbox-routing": "^3.6.3", + "workbox-strategies": "^3.6.3" + } + }, + "workbox-navigation-preload": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-3.6.3.tgz", + "integrity": "sha512-dd26xTX16DUu0i+MhqZK/jQXgfIitu0yATM4jhRXEmpMqQ4MxEeNvl2CgjDMOHBnCVMax+CFZQWwxMx/X/PqCw==", + "dev": true, + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-precaching": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-3.6.3.tgz", + "integrity": "sha512-aBqT66BuMFviPTW6IpccZZHzpA8xzvZU2OM1AdhmSlYDXOJyb1+Z6blVD7z2Q8VNtV1UVwQIdImIX+hH3C3PIw==", + "dev": true, + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-range-requests": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-3.6.3.tgz", + "integrity": "sha512-R+yLWQy7D9aRF9yJ3QzwYnGFnGDhMUij4jVBUVtkl67oaVoP1ymZ81AfCmfZro2kpPRI+vmNMfxxW531cqdx8A==", + "dev": true, + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-routing": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-3.6.3.tgz", + "integrity": "sha512-bX20i95OKXXQovXhFOViOK63HYmXvsIwZXKWbSpVeKToxMrp0G/6LZXnhg82ijj/S5yhKNRf9LeGDzaqxzAwMQ==", + "dev": true, + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-strategies": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-3.6.3.tgz", + "integrity": "sha512-Pg5eulqeKet2y8j73Yw6xTgLdElktcWExGkzDVCGqfV9JCvnGuEpz5eVsCIK70+k4oJcBCin9qEg3g3CwEIH3g==", + "dev": true, + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-streams": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-3.6.3.tgz", + "integrity": "sha512-rqDuS4duj+3aZUYI1LsrD2t9hHOjwPqnUIfrXSOxSVjVn83W2MisDF2Bj+dFUZv4GalL9xqErcFW++9gH+Z27w==", + "dev": true, + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-sw": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-3.6.3.tgz", + "integrity": "sha512-IQOUi+RLhvYCiv80RP23KBW/NTtIvzvjex28B8NW1jOm+iV4VIu3VXKXTA6er5/wjjuhmtB28qEAUqADLAyOSg==", + "dev": true + }, + "workbox-webpack-plugin": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-3.6.3.tgz", + "integrity": "sha512-RwmKjc7HFHUFHoOlKoZUq9349u0QN3F8W5tZZU0vc1qsBZDINWXRiIBCAKvo/Njgay5sWz7z4I2adnyTo97qIQ==", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "json-stable-stringify": "^1.0.1", + "workbox-build": "^3.6.3" + } + }, + "worker-farm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz", + "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write-file-atomic": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz", + "integrity": "sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "xregexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz", + "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yorkie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yorkie/-/yorkie-2.0.0.tgz", + "integrity": "sha512-jcKpkthap6x63MB4TxwCyuIGkV0oYP/YRyuQU5UO0Yz/E/ZAu+653/uov+phdmO54n6BcvFRyyt0RRrWdN2mpw==", + "dev": true, + "requires": { + "execa": "^0.8.0", + "is-ci": "^1.0.10", + "normalize-path": "^1.0.0", + "strip-indent": "^2.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", + "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", + "dev": true, + "requires": { + "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" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "normalize-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz", + "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } + } + } +} diff --git a/{{cookiecutter.project_slug}}/frontend/package.json b/{{cookiecutter.project_slug}}/frontend/package.json new file mode 100644 index 0000000..3a792b7 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/package.json @@ -0,0 +1,73 @@ +{ + "name": "frontend", + "version": "0.1.0", + "private": true, + "scripts": { + "serve": "vue-cli-service serve", + "build": "vue-cli-service build", + "lint": "vue-cli-service lint", + "test:unit": "vue-cli-service test:unit" + }, + "dependencies": { + "@babel/polyfill": "^7.2.5", + "axios": "^0.18.0", + "register-service-worker": "^1.0.0", + "typesafe-vuex": "^3.1.1", + "vee-validate": "^2.1.7", + "vue": "^2.5.22", + "vue-class-component": "^6.0.0", + "vue-property-decorator": "^7.3.0", + "vue-router": "^3.0.2", + "vuetify": "^1.4.4", + "vuex": "^3.1.0" + }, + "devDependencies": { + "@types/jest": "^23.3.13", + "@vue/cli-plugin-babel": "^3.3.0", + "@vue/cli-plugin-pwa": "^3.3.0", + "@vue/cli-plugin-typescript": "^3.3.0", + "@vue/cli-plugin-unit-jest": "^3.3.0", + "@vue/cli-service": "^3.3.1", + "@vue/test-utils": "^1.0.0-beta.28", + "babel-core": "7.0.0-bridge.0", + "ts-jest": "^23.10.5", + "typescript": "^3.2.4", + "vue-cli-plugin-vuetify": "^0.2.1", + "vue-template-compiler": "^2.5.22" + }, + "postcss": { + "plugins": { + "autoprefixer": {} + } + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 10" + ], + "jest": { + "moduleFileExtensions": [ + "js", + "jsx", + "json", + "vue", + "ts", + "tsx" + ], + "transform": { + "^.+\\.vue$": "vue-jest", + ".+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$": "jest-transform-stub", + "^.+\\.tsx?$": "ts-jest" + }, + "moduleNameMapper": { + "^@/(.*)$": "/src/$1" + }, + "snapshotSerializers": [ + "jest-serializer-vue" + ], + "testMatch": [ + "**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)" + ], + "testURL": "http://localhost/" + } +} diff --git a/{{cookiecutter.project_slug}}/frontend/public/favicon.ico b/{{cookiecutter.project_slug}}/frontend/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c7b9a43c8cd16d0b434adaf513fcacb340809a11 GIT binary patch literal 1150 zcmchVOGsN$5QZm2NTI$erQpKHrdQX(jn+pVxKN`Ng)RzW5+8_2Xb@Y)Dkd6tq9V8u z3WAh^C@KZ1kA;tohzs}b3NC_*QmUXr$oP*rH(2mdT{z*(KX=aj=bX$9kqMvFRKj;Q zwI&d~A);J>5-PDega~WT5us%#Dc(Y}C4WpP?+fS;FaZ*z_CFzgiW=w{I02=q_TUz( z?=^H2uwoIK1n%|Ay21~QgjV1emYtWttJdz^L#=DjJ@Ex*9UPc*7<=rZo*_NAh4PxA zqkso~Ioa1y$e+3kIkXi29YNLi&lW}vY6C}ut4{8ou(7w=$_=$v{yJ$h?y!&bJfq*( zL_NQRF37$6e>%9erGV?p^lRFD?|5J_eupXaS;QluyrOmBT>PJhirMYb*i?(4Tf=j~?VvnUlY_ zDCVuuk3E&T9aP~Cr-0i-MaKUjf_|U!=R&t}_CfD=d${p~HH`BPaqb9aXT}UI$iGRg z>0^GlZ`vM4?;$*LhfI(RG|XK4GF+@-W*W}YJT5&2N_ZyZuaM_Ry=%PWx>r0P(Rc?> jRc4}SfGA>*agjwN{7E7DEm(*)%rSx{B0<6wBoglxJAy|R literal 0 HcmV?d00001 diff --git a/{{cookiecutter.project_slug}}/frontend/public/img/icons/android-chrome-192x192.png b/{{cookiecutter.project_slug}}/frontend/public/img/icons/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..b02aa64d97167ad649e496908b35f14c603d9249 GIT binary patch literal 9416 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 ROru=^AazZ3N)e9H{|11FNXq~K literal 0 HcmV?d00001 diff --git a/{{cookiecutter.project_slug}}/frontend/public/img/icons/apple-touch-icon-152x152.png b/{{cookiecutter.project_slug}}/frontend/public/img/icons/apple-touch-icon-152x152.png new file mode 100644 index 0000000000000000000000000000000000000000..f24d454a2ecb8851bb893192b64ee09386d30e24 GIT binary patch literal 4046 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 cK^5JQ0?3d{m_4Kdj*!1;003@kYpI!lw*K!+ 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�MrHbYR_buu=L>f*wO=Er8~{qfkYT+HoHag8)VqJoC-#@ zNT})4xRE%sP-B9?xmL5!2Y8VLa?yj@Y@r1C)6o~9GF9nWG!SI2VJ$>ejtUE%Qv&r_ zYLgZ0h3iIrw7{TyurC(g^$XT%PP5`FB3aFpP&fM-8!J#3I_ujG?;7(Xv5ni%BjYP4 z^+oydy=)_&bdxYJx`X%G5PFkUB%3h6RiOs^F?#ojsB%DbfhqzGhuv4)S1%vw@PDyE z3xWF{Y^0>+=Wg! z{>z@$rD6ej*V- z^$zKIOWOfdN4~7@ndhru01+3cxwD&_Muyja({*O;-5VnF(e$WDALNStE{1{F#ts+VR{o zSlQ*@U=Du8fgKW$lU~)O)b6FS?H1SSnKVIC=DOvbo8IUvM zVf+U4YxG%qLGd%ew7Jp8>@U`ew+A#Q=2oJHNH@_f!WadS20$KZEZ+BHAvU@FB zzRCYN5r+Z#g`C^hrH$yW7ABstwjvMM*CHGzY41bbo2zy$6E8DAOPn zUnHG?e7?u7pQ}Kqbu1jEd+=mcGea4aL6V4g(m*b7x}z|ijsjb3e|tf-3&^JK{=sWz z8sqIu9jy)#J}n}cXqtXmkb-NDVPcAKn=G9uX42zYvufu_OCr>xJ=oTNp8WA5wEqvM z{r~m8;7_C>U68iRr@|rd7UYhON#(-S_+Uf>s)hhPU{{exlxc&eD literal 0 HcmV?d00001 diff --git a/{{cookiecutter.project_slug}}/frontend/public/img/icons/apple-touch-icon-60x60.png b/{{cookiecutter.project_slug}}/frontend/public/img/icons/apple-touch-icon-60x60.png new file mode 100644 index 0000000000000000000000000000000000000000..cf10a5602e653bb126332934e2b7f34081c19a01 GIT binary patch literal 1491 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

aZW9cb|x>1jZDoAu$NpeWiVk@{x{! zmmBmDgx|qNN?LyIrl9$qmj{KjZ8zpa=4edK3FuFS$KFl}bWPoO*Ax#Z1c2#3JAN(O zYhi>`%H9fSnLkAq|5vs>+?U*bdfMc6TmDu+QqnN9xgfZsG25($^;v7U1nBl9Q^o*i z)&?UaYZ=~7XZa75xPKB1s~MB1m<*dN08pqiy*q!)_Kc|;EZs3&nNdMQ5#LFu+J z?*($vO)$hkMOVc16f-ep;K@_~&Y6t?0t9I0(lBkZBfic|u)3pK$Xv=A@jUQnB2sC` zbI)L9m;VNkWOao}2c3b4_u4+bg zuf-@d1$?asdD1~mORQ02#!&1Xm#41*xz}wETNqKb;kueQ*~OpcAXTpJFYUYcKoA&Z z8Ke=2Vh~cu_uTb&6AH75L!k8zo~&wRsDLs^3YkD2!~;%u6sFrzV2A5(FQ|3}+0-K- zWX)W2yq%?^)iKhyMGPB5*DnWBaLqAHLJ47;r5nvkeq3u_?J{Xaf_}6I+xpLwKS7NC z|KYU%zup)8i85jc)^Yt*I0W8;+zHUI3V7@o;3DUYasdq>DFK%im4J)F?;|B-<=}8R z>HESGa5)KyCnGII|E+YX&h4Y+xCRvyX@oGhhG4 j58+{W$RJv~NLLKlV4)8v^7hU(R-4l(}$teLl` literal 0 HcmV?d00001 diff --git a/{{cookiecutter.project_slug}}/frontend/public/img/icons/favicon-16x16.png b/{{cookiecutter.project_slug}}/frontend/public/img/icons/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..42af00963d81b8e39a30435c60ac482d1f8756e0 GIT binary patch literal 799 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>WRE8{w#)hawXn|-Xp4{E;v!=;4B^%-x&;Cm1 zP>^*#n_J!T^1SBMI!C4h-R53dN8`?ylD}d{L%(vZvUKT)~-CgWFQy3lt zIqW5#zOL*K8HL%o&D;R|TePl5?VWhq^wrj^qed%lKKkpp-FogeyEi+p zE?K8rW7E1fuEJ{5jaaAp0~aIt+keS?T)@vXM=*X}V#VGMCm1~v-+0wr{w3CJ-R8wG zS@XVpzqP-5Mf0H?y-zh=XVL>S6E;rKnDmrMQlmoKbK9p$evXN`oe{6g>lvi)-+#c) zb+Al&$zRqtWk1@VTt6MPmq9d7^!kmXZn8k{sFt`!l%ynwlArU1(iRB6fMfqu& zIjIUIl?AB^nFS@u3=9=>9)IHDC=AokIOTu(jOWuJ24-b$y<~1-Wnu5hBFw@HE)6D! wQ<#-EhbWxBaplC3Ge=~Ou%B-5Sm33{@Jd{;RG<|Mp00i_>zopr0DGh}-~a#s literal 0 HcmV?d00001 diff --git a/{{cookiecutter.project_slug}}/frontend/public/img/icons/favicon-32x32.png b/{{cookiecutter.project_slug}}/frontend/public/img/icons/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..46ca04dee251a4fa85a2891a145fbe20cc619d96 GIT binary patch literal 1271 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 + + + +Created by potrace 1.11, written by Peter Selinger 2001-2013 + + + + + diff --git a/{{cookiecutter.project_slug}}/frontend/public/index.html b/{{cookiecutter.project_slug}}/frontend/public/index.html new file mode 100644 index 0000000..cad5aa7 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/public/index.html @@ -0,0 +1,21 @@ + + + + + + + + <%= VUE_APP_NAME %> + + + + + + + +

+ + + diff --git a/{{cookiecutter.project_slug}}/frontend/public/manifest.json b/{{cookiecutter.project_slug}}/frontend/public/manifest.json new file mode 100644 index 0000000..8ce10b9 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/public/manifest.json @@ -0,0 +1,20 @@ +{ + "name": "frontend", + "short_name": "frontend", + "icons": [ + { + "src": "/img/icons/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/img/icons/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "start_url": "/", + "display": "standalone", + "background_color": "#000000", + "theme_color": "#4DBA87" +} diff --git a/{{cookiecutter.project_slug}}/frontend/public/robots.txt b/{{cookiecutter.project_slug}}/frontend/public/robots.txt new file mode 100644 index 0000000..eb05362 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: diff --git a/{{cookiecutter.project_slug}}/frontend/src/App.vue b/{{cookiecutter.project_slug}}/frontend/src/App.vue new file mode 100644 index 0000000..01c2c2a --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/App.vue @@ -0,0 +1,42 @@ + + + diff --git a/{{cookiecutter.project_slug}}/frontend/src/api.ts b/{{cookiecutter.project_slug}}/frontend/src/api.ts new file mode 100644 index 0000000..9899070 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/api.ts @@ -0,0 +1,48 @@ +import axios from 'axios'; +import { apiUrl } from '@/env'; +import { IUserProfile, IUserProfileUpdate, IUserProfileCreate } from './interfaces'; + +function authHeaders(token: string) { + return { + headers: { + Authorization: `Bearer ${token}`, + }, + }; +} + +export const api = { + async logInGetToken(username: string, password: string) { + const params = new URLSearchParams(); + params.append('username', username); + params.append('password', password); + + return axios.post(`${apiUrl}/api/v1/login/access-token`, params); + }, + async getMe(token: string) { + return axios.get(`${apiUrl}/api/v1/users/me`, authHeaders(token)); + }, + async updateMe(token: string, data: IUserProfileUpdate) { + return axios.put(`${apiUrl}/api/v1/users/me`, data, authHeaders(token)); + }, + async getUsers(token: string) { + return axios.get(`${apiUrl}/api/v1/users/`, authHeaders(token)); + }, + async updateUser(token: string, name: string, data: IUserProfileUpdate) { + return axios.put(`${apiUrl}/api/v1/users/${name}`, data, authHeaders(token)); + }, + async createUser(token: string, data: IUserProfileCreate) { + return axios.post(`${apiUrl}/api/v1/users/`, data, authHeaders(token)); + }, + async getRoles(token: string) { + return axios.get(`${apiUrl}/api/v1/roles/`, authHeaders(token)); + }, + async passwordRecovery(username: string) { + return axios.post(`${apiUrl}/api/v1/password-recovery/${username}`); + }, + async resetPassword(password: string, token: string) { + return axios.post(`${apiUrl}/api/v1/reset-password/`, { + new_password: password, + token, + }); + }, +}; diff --git a/{{cookiecutter.project_slug}}/frontend/src/assets/logo.png b/{{cookiecutter.project_slug}}/frontend/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 zcmaKRcUV(fvo}bjDT-7nLI_nlK}sT_69H+`qzVWDA|yaU?}j417wLi^B1KB1SLsC& zL0ag7$U(XW5YR7p&Ux?sP$d4lvMt8C^+TcQu4F zQqv!UF!I+kw)c0jhd6+g6oCr9P?7)?!qX1ui*iL{p}sKCAGuJ{{W)0z1pLF|=>h}& zt(2Lr0Z`2ig8<5i%Zk}cO5Fm=LByqGWaS`oqChZdEFmc`0hSb#gg|Aap^{+WKOYcj zHjINK)KDG%&s?Mt4CL(T=?;~U@bU2x_mLKN!#GJuK_CzbNw5SMEJorG!}_5;?R>@1 zSl)jns3WlU7^J%=(hUtfmuUCU&C3%8B5C^f5>W2Cy8jW3#{Od{lF1}|?c61##3dzA zsPlFG;l_FzBK}8>|H_Ru_H#!_7$UH4UKo3lKOA}g1(R&|e@}GINYVzX?q=_WLZCgh z)L|eJMce`D0EIwgRaNETDsr+?vQknSGAi=7H00r`QnI%oQnFxm`G2umXso9l+8*&Q z7WqF|$p49js$mdzo^BXpH#gURy=UO;=IMrYc5?@+sR4y_?d*~0^YP7d+y0{}0)zBM zIKVM(DBvICK#~7N0a+PY6)7;u=dutmNqK3AlsrUU9U`d;msiucB_|8|2kY=(7XA;G zwDA8AR)VCA#JOkxm#6oHNS^YVuOU;8p$N)2{`;oF|rQ?B~K$%rHDxXs+_G zF5|-uqHZvSzq}L;5Kcy_P+x0${33}Ofb6+TX&=y;;PkEOpz%+_bCw_{<&~ zeLV|!bP%l1qxywfVr9Z9JI+++EO^x>ZuCK);=$VIG1`kxK8F2M8AdC$iOe3cj1fo(ce4l-9 z7*zKy3={MixvUk=enQE;ED~7tv%qh&3lR<0m??@w{ILF|e#QOyPkFYK!&Up7xWNtL zOW%1QMC<3o;G9_S1;NkPB6bqbCOjeztEc6TsBM<(q9((JKiH{01+Ud=uw9B@{;(JJ z-DxI2*{pMq`q1RQc;V8@gYAY44Z!%#W~M9pRxI(R?SJ7sy7em=Z5DbuDlr@*q|25V)($-f}9c#?D%dU^RS<(wz?{P zFFHtCab*!rl(~j@0(Nadvwg8q|4!}L^>d?0al6}Rrv9$0M#^&@zjbfJy_n!%mVHK4 z6pLRIQ^Uq~dnyy$`ay51Us6WaP%&O;@49m&{G3z7xV3dLtt1VTOMYl3UW~Rm{Eq4m zF?Zl_v;?7EFx1_+#WFUXxcK78IV)FO>42@cm@}2I%pVbZqQ}3;p;sDIm&knay03a^ zn$5}Q$G!@fTwD$e(x-~aWP0h+4NRz$KlnO_H2c< z(XX#lPuW_%H#Q+c&(nRyX1-IadKR-%$4FYC0fsCmL9ky3 zKpxyjd^JFR+vg2!=HWf}2Z?@Td`0EG`kU?{8zKrvtsm)|7>pPk9nu@2^z96aU2<#` z2QhvH5w&V;wER?mopu+nqu*n8p~(%QkwSs&*0eJwa zMXR05`OSFpfyRb!Y_+H@O%Y z0=K^y6B8Gcbl?SA)qMP3Z+=C(?8zL@=74R=EVnE?vY!1BQy2@q*RUgRx4yJ$k}MnL zs!?74QciNb-LcG*&o<9=DSL>1n}ZNd)w1z3-0Pd^4ED1{qd=9|!!N?xnXjM!EuylY z5=!H>&hSofh8V?Jofyd!h`xDI1fYAuV(sZwwN~{$a}MX^=+0TH*SFp$vyxmUv7C*W zv^3Gl0+eTFgBi3FVD;$nhcp)ka*4gSskYIqQ&+M}xP9yLAkWzBI^I%zR^l1e?bW_6 zIn{mo{dD=)9@V?s^fa55jh78rP*Ze<3`tRCN4*mpO$@7a^*2B*7N_|A(Ve2VB|)_o z$=#_=aBkhe(ifX}MLT()@5?OV+~7cXC3r!%{QJxriXo9I%*3q4KT4Xxzyd{ z9;_%=W%q!Vw$Z7F3lUnY+1HZ*lO;4;VR2+i4+D(m#01OYq|L_fbnT;KN<^dkkCwtd zF7n+O7KvAw8c`JUh6LmeIrk4`F3o|AagKSMK3))_5Cv~y2Bb2!Ibg9BO7Vkz?pAYX zoI=B}+$R22&IL`NCYUYjrdhwjnMx_v=-Qcx-jmtN>!Zqf|n1^SWrHy zK|MwJ?Z#^>)rfT5YSY{qjZ&`Fjd;^vv&gF-Yj6$9-Dy$<6zeP4s+78gS2|t%Z309b z0^fp~ue_}i`U9j!<|qF92_3oB09NqgAoehQ`)<)dSfKoJl_A6Ec#*Mx9Cpd-p#$Ez z={AM*r-bQs6*z$!*VA4|QE7bf@-4vb?Q+pPKLkY2{yKsw{&udv_2v8{Dbd zm~8VAv!G~s)`O3|Q6vFUV%8%+?ZSVUa(;fhPNg#vab@J*9XE4#D%)$UU-T5`fwjz! z6&gA^`OGu6aUk{l*h9eB?opVdrHK>Q@U>&JQ_2pR%}TyOXGq_6s56_`U(WoOaAb+K zXQr#6H}>a-GYs9^bGP2Y&hSP5gEtW+GVC4=wy0wQk=~%CSXj=GH6q z-T#s!BV`xZVxm{~jr_ezYRpqqIcXC=Oq`b{lu`Rt(IYr4B91hhVC?yg{ol4WUr3v9 zOAk2LG>CIECZ-WIs0$N}F#eoIUEtZudc7DPYIjzGqDLWk_A4#(LgacooD z2K4IWs@N`Bddm-{%oy}!k0^i6Yh)uJ1S*90>|bm3TOZxcV|ywHUb(+CeX-o1|LTZM zwU>dY3R&U)T(}5#Neh?-CWT~@{6Ke@sI)uSuzoah8COy)w)B)aslJmp`WUcjdia-0 zl2Y}&L~XfA`uYQboAJ1;J{XLhYjH){cObH3FDva+^8ioOQy%Z=xyjGLmWMrzfFoH; zEi3AG`_v+%)&lDJE;iJWJDI@-X9K5O)LD~j*PBe(wu+|%ar~C+LK1+-+lK=t# z+Xc+J7qp~5q=B~rD!x78)?1+KUIbYr^5rcl&tB-cTtj+e%{gpZZ4G~6r15+d|J(ky zjg@@UzMW0k9@S#W(1H{u;Nq(7llJbq;;4t$awM;l&(2s+$l!Ay9^Ge|34CVhr7|BG z?dAR83smef^frq9V(OH+a+ki#q&-7TkWfFM=5bsGbU(8mC;>QTCWL5ydz9s6k@?+V zcjiH`VI=59P-(-DWXZ~5DH>B^_H~;4$)KUhnmGo*G!Tq8^LjfUDO)lASN*=#AY_yS zqW9UX(VOCO&p@kHdUUgsBO0KhXxn1sprK5h8}+>IhX(nSXZKwlNsjk^M|RAaqmCZB zHBolOHYBas@&{PT=R+?d8pZu zUHfyucQ`(umXSW7o?HQ3H21M`ZJal+%*)SH1B1j6rxTlG3hx1IGJN^M7{$j(9V;MZ zRKybgVuxKo#XVM+?*yTy{W+XHaU5Jbt-UG33x{u(N-2wmw;zzPH&4DE103HV@ER86 z|FZEmQb|&1s5#`$4!Cm}&`^{(4V}OP$bk`}v6q6rm;P!H)W|2i^e{7lTk2W@jo_9q z*aw|U7#+g59Fv(5qI`#O-qPj#@_P>PC#I(GSp3DLv7x-dmYK=C7lPF8a)bxb=@)B1 zUZ`EqpXV2dR}B&r`uM}N(TS99ZT0UB%IN|0H%DcVO#T%L_chrgn#m6%x4KE*IMfjX zJ%4veCEqbXZ`H`F_+fELMC@wuy_ch%t*+Z+1I}wN#C+dRrf2X{1C8=yZ_%Pt6wL_~ zZ2NN-hXOT4P4n$QFO7yYHS-4wF1Xfr-meG9Pn;uK51?hfel`d38k{W)F*|gJLT2#T z<~>spMu4(mul-8Q3*pf=N4DcI)zzjqAgbE2eOT7~&f1W3VsdD44Ffe;3mJp-V@8UC z)|qnPc12o~$X-+U@L_lWqv-RtvB~%hLF($%Ew5w>^NR82qC_0FB z)=hP1-OEx?lLi#jnLzH}a;Nvr@JDO-zQWd}#k^an$Kwml;MrD&)sC5b`s0ZkVyPkb zt}-jOq^%_9>YZe7Y}PhW{a)c39G`kg(P4@kxjcYfgB4XOOcmezdUI7j-!gs7oAo2o zx(Ph{G+YZ`a%~kzK!HTAA5NXE-7vOFRr5oqY$rH>WI6SFvWmahFav!CfRMM3%8J&c z*p+%|-fNS_@QrFr(at!JY9jCg9F-%5{nb5Bo~z@Y9m&SHYV`49GAJjA5h~h4(G!Se zZmK{Bo7ivCfvl}@A-ptkFGcWXAzj3xfl{evi-OG(TaCn1FAHxRc{}B|x+Ua1D=I6M z!C^ZIvK6aS_c&(=OQDZfm>O`Nxsw{ta&yiYPA~@e#c%N>>#rq)k6Aru-qD4(D^v)y z*>Rs;YUbD1S8^D(ps6Jbj0K3wJw>L4m)0e(6Pee3Y?gy9i0^bZO?$*sv+xKV?WBlh zAp*;v6w!a8;A7sLB*g-^<$Z4L7|5jXxxP1}hQZ<55f9<^KJ>^mKlWSGaLcO0=$jem zWyZkRwe~u{{tU63DlCaS9$Y4CP4f?+wwa(&1ou)b>72ydrFvm`Rj-0`kBJgK@nd(*Eh!(NC{F-@=FnF&Y!q`7){YsLLHf0_B6aHc# z>WIuHTyJwIH{BJ4)2RtEauC7Yq7Cytc|S)4^*t8Va3HR zg=~sN^tp9re@w=GTx$;zOWMjcg-7X3Wk^N$n;&Kf1RgVG2}2L-(0o)54C509C&77i zrjSi{X*WV=%C17((N^6R4Ya*4#6s_L99RtQ>m(%#nQ#wrRC8Y%yxkH;d!MdY+Tw@r zjpSnK`;C-U{ATcgaxoEpP0Gf+tx);buOMlK=01D|J+ROu37qc*rD(w`#O=3*O*w9?biwNoq3WN1`&Wp8TvKj3C z3HR9ssH7a&Vr<6waJrU zdLg!ieYz%U^bmpn%;(V%%ugMk92&?_XX1K@mwnVSE6!&%P%Wdi7_h`CpScvspMx?N zQUR>oadnG17#hNc$pkTp+9lW+MBKHRZ~74XWUryd)4yd zj98$%XmIL4(9OnoeO5Fnyn&fpQ9b0h4e6EHHw*l68j;>(ya`g^S&y2{O8U>1*>4zR zq*WSI_2o$CHQ?x0!wl9bpx|Cm2+kFMR)oMud1%n2=qn5nE&t@Fgr#=Zv2?}wtEz^T z9rrj=?IH*qI5{G@Rn&}^Z{+TW}mQeb9=8b<_a`&Cm#n%n~ zU47MvCBsdXFB1+adOO)03+nczfWa#vwk#r{o{dF)QWya9v2nv43Zp3%Ps}($lA02*_g25t;|T{A5snSY?3A zrRQ~(Ygh_ebltHo1VCbJb*eOAr;4cnlXLvI>*$-#AVsGg6B1r7@;g^L zFlJ_th0vxO7;-opU@WAFe;<}?!2q?RBrFK5U{*ai@NLKZ^};Ul}beukveh?TQn;$%9=R+DX07m82gP$=}Uo_%&ngV`}Hyv8g{u z3SWzTGV|cwQuFIs7ZDOqO_fGf8Q`8MwL}eUp>q?4eqCmOTcwQuXtQckPy|4F1on8l zP*h>d+cH#XQf|+6c|S{7SF(Lg>bR~l(0uY?O{OEVlaxa5@e%T&xju=o1`=OD#qc16 zSvyH*my(dcp6~VqR;o(#@m44Lug@~_qw+HA=mS#Z^4reBy8iV?H~I;{LQWk3aKK8$bLRyt$g?- +
+ + {{ currentNotificationContent }} + Close + +
+ + diff --git a/{{cookiecutter.project_slug}}/frontend/src/components/RouterComponent.vue b/{{cookiecutter.project_slug}}/frontend/src/components/RouterComponent.vue new file mode 100644 index 0000000..ed986a6 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/components/RouterComponent.vue @@ -0,0 +1,11 @@ + + + diff --git a/{{cookiecutter.project_slug}}/frontend/src/components/UploadButton.vue b/{{cookiecutter.project_slug}}/frontend/src/components/UploadButton.vue new file mode 100644 index 0000000..8902e94 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/components/UploadButton.vue @@ -0,0 +1,34 @@ + + + + + diff --git a/{{cookiecutter.project_slug}}/frontend/src/env.ts b/{{cookiecutter.project_slug}}/frontend/src/env.ts new file mode 100644 index 0000000..b3387e6 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/env.ts @@ -0,0 +1,14 @@ +const env = process.env.VUE_APP_ENV; + +let envApiUrl = ''; + +if (env === 'production') { + envApiUrl = `https://${process.env.VUE_APP_DOMAIN_PROD}`; +} else if (env === 'staging') { + envApiUrl = `https://${process.env.VUE_APP_DOMAIN_STAG}`; +} else { + envApiUrl = `http://${process.env.VUE_APP_DOMAIN_DEV}`; +} + +export const apiUrl = envApiUrl; +export const appName = process.env.VUE_APP_NAME; diff --git a/{{cookiecutter.project_slug}}/frontend/src/interfaces/index.ts b/{{cookiecutter.project_slug}}/frontend/src/interfaces/index.ts new file mode 100644 index 0000000..321835e --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/interfaces/index.ts @@ -0,0 +1,27 @@ +export interface IUserProfile { + admin_channels: string[]; + admin_roles: string[]; + disabled: boolean; + email: string; + human_name: string; + name: string; +} + +export interface IUserProfileUpdate { + human_name?: string; + password?: string; + email?: string; + admin_channels?: string[]; + admin_roles?: string[]; + disabled?: boolean; +} + +export interface IUserProfileCreate { + name: string; + human_name?: string; + password?: string; + email?: string; + admin_channels?: string[]; + admin_roles?: string[]; + disabled?: boolean; +} diff --git a/{{cookiecutter.project_slug}}/frontend/src/main.ts b/{{cookiecutter.project_slug}}/frontend/src/main.ts new file mode 100644 index 0000000..a844b1e --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/main.ts @@ -0,0 +1,19 @@ +import '@babel/polyfill'; +// Import Component hooks before component definitions +import './component-hooks'; +import Vue from 'vue'; +import './plugins/vuetify'; +import './plugins/vee-validate'; +import App from './App.vue'; +import router from './router'; +import store from '@/store'; +import './registerServiceWorker'; +import 'vuetify/dist/vuetify.min.css'; + +Vue.config.productionTip = false; + +new Vue({ + router, + store, + render: (h) => h(App), +}).$mount('#app'); diff --git a/{{cookiecutter.project_slug}}/frontend/src/plugins/vee-validate.ts b/{{cookiecutter.project_slug}}/frontend/src/plugins/vee-validate.ts new file mode 100644 index 0000000..9c4238f --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/plugins/vee-validate.ts @@ -0,0 +1,4 @@ +import Vue from 'vue'; +import VeeValidate from 'vee-validate'; + +Vue.use(VeeValidate); diff --git a/{{cookiecutter.project_slug}}/frontend/src/plugins/vuetify.ts b/{{cookiecutter.project_slug}}/frontend/src/plugins/vuetify.ts new file mode 100644 index 0000000..8fdfce3 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/plugins/vuetify.ts @@ -0,0 +1,6 @@ +import Vue from 'vue'; +import Vuetify from 'vuetify'; + +Vue.use(Vuetify, { + iconfont: 'md', +}); diff --git a/{{cookiecutter.project_slug}}/frontend/src/registerServiceWorker.ts b/{{cookiecutter.project_slug}}/frontend/src/registerServiceWorker.ts new file mode 100644 index 0000000..d3db583 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/registerServiceWorker.ts @@ -0,0 +1,26 @@ +/* tslint:disable:no-console */ + +import { register } from 'register-service-worker'; + +if (process.env.NODE_ENV === 'production') { + register(`${process.env.BASE_URL}service-worker.js`, { + ready() { + console.log( + 'App is being served from cache by a service worker.\n' + + 'For more details, visit https://goo.gl/AFskqB', + ); + }, + cached() { + console.log('Content has been cached for offline use.'); + }, + updated() { + console.log('New content is available; please refresh.'); + }, + offline() { + console.log('No internet connection found. App is running in offline mode.'); + }, + error(error) { + console.error('Error during service worker registration:', error); + }, + }); +} diff --git a/{{cookiecutter.project_slug}}/frontend/src/router.ts b/{{cookiecutter.project_slug}}/frontend/src/router.ts new file mode 100644 index 0000000..87db7a9 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/router.ts @@ -0,0 +1,97 @@ +import Vue from 'vue'; +import Router from 'vue-router'; + +import RouterComponent from './components/RouterComponent.vue'; + +Vue.use(Router); + +export default new Router({ + mode: 'history', + base: process.env.BASE_URL, + routes: [ + { + path: '/', + component: () => import(/* webpackChunkName: "start" */ './views/main/Start.vue'), + children: [ + { + path: 'login', + // route level code-splitting + // this generates a separate chunk (about.[hash].js) for this route + // which is lazy-loaded when the route is visited. + component: () => import(/* webpackChunkName: "login" */ './views/Login.vue'), + }, + { + path: 'recover-password', + component: () => import(/* webpackChunkName: "recover-password" */ './views/PasswordRecovery.vue'), + }, + { + path: 'reset-password', + component: () => import(/* webpackChunkName: "reset-password" */ './views/ResetPassword.vue'), + }, + { + path: 'main', + component: () => import(/* webpackChunkName: "main" */ './views/main/Main.vue'), + children: [ + { + path: 'dashboard', + component: () => import(/* webpackChunkName: "main-dashboard" */ './views/main/Dashboard.vue'), + }, + { + path: 'profile', + component: RouterComponent, + redirect: 'profile/view', + children: [ + { + path: 'view', + component: () => import( + /* webpackChunkName: "main-profile" */ './views/main/profile/UserProfile.vue'), + }, + { + path: 'edit', + component: () => import( + /* webpackChunkName: "main-profile-edit" */ './views/main/profile/UserProfileEdit.vue'), + }, + { + path: 'password', + component: () => import( + /* webpackChunkName: "main-profile-password" */ './views/main/profile/UserProfileEditPassword.vue'), + }, + ], + }, + { + path: 'admin', + component: () => import(/* webpackChunkName: "main-admin" */ './views/main/admin/Admin.vue'), + redirect: 'admin/users/all', + children: [ + { + path: 'users', + redirect: 'users/all', + }, + { + path: 'users/all', + component: () => import( + /* webpackChunkName: "main-admin-users" */ './views/main/admin/AdminUsers.vue'), + }, + { + path: 'users/edit/:name', + name: 'main-admin-users-edit', + component: () => import( + /* webpackChunkName: "main-admin-users-edit" */ './views/main/admin/EditUser.vue'), + }, + { + path: 'users/create', + name: 'main-admin-users-create', + component: () => import( + /* webpackChunkName: "main-admin-users-create" */ './views/main/admin/CreateUser.vue'), + }, + ], + }, + ], + }, + ], + }, + { + path: '/*', redirect: '/', + }, + ], +}); diff --git a/{{cookiecutter.project_slug}}/frontend/src/shims-tsx.d.ts b/{{cookiecutter.project_slug}}/frontend/src/shims-tsx.d.ts new file mode 100644 index 0000000..3b88b58 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/shims-tsx.d.ts @@ -0,0 +1,13 @@ +import Vue, { VNode } from 'vue'; + +declare global { + namespace JSX { + // tslint:disable no-empty-interface + interface Element extends VNode {} + // tslint:disable no-empty-interface + interface ElementClass extends Vue {} + interface IntrinsicElements { + [elem: string]: any; + } + } +} diff --git a/{{cookiecutter.project_slug}}/frontend/src/shims-vue.d.ts b/{{cookiecutter.project_slug}}/frontend/src/shims-vue.d.ts new file mode 100644 index 0000000..8f6f410 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/shims-vue.d.ts @@ -0,0 +1,4 @@ +declare module '*.vue' { + import Vue from 'vue'; + export default Vue; +} diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/admin/accessors/commit.ts b/{{cookiecutter.project_slug}}/frontend/src/store/admin/accessors/commit.ts new file mode 100644 index 0000000..c8c5e85 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/admin/accessors/commit.ts @@ -0,0 +1,10 @@ +import { getStoreAccessors } from 'typesafe-vuex'; +import { State } from '@/store/state'; +import { mutations } from '../mutations'; +import { AdminState } from '../state'; + +const {commit} = getStoreAccessors(''); + +export const commitSetRoles = commit(mutations.setRoles); +export const commitSetUser = commit(mutations.setUser); +export const commitSetUsers = commit(mutations.setUsers); diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/admin/accessors/dispatch.ts b/{{cookiecutter.project_slug}}/frontend/src/store/admin/accessors/dispatch.ts new file mode 100644 index 0000000..bd677cd --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/admin/accessors/dispatch.ts @@ -0,0 +1,11 @@ +import { getStoreAccessors } from 'typesafe-vuex'; +import { AdminState } from '../state'; +import { State } from '@/store/state'; +import { actions } from '../actions'; + +const {dispatch} = getStoreAccessors(''); + +export const dispatchCreateUser = dispatch(actions.actionCreateUser); +export const dispatchGetRoles = dispatch(actions.actionGetRoles); +export const dispatchGetUsers = dispatch(actions.actionGetUsers); +export const dispatchUpdateUser = dispatch(actions.actionUpdateUser); diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/admin/accessors/index.ts b/{{cookiecutter.project_slug}}/frontend/src/store/admin/accessors/index.ts new file mode 100644 index 0000000..5486b2e --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/admin/accessors/index.ts @@ -0,0 +1,3 @@ +export * from './commit'; +export * from './dispatch'; +export * from './read'; diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/admin/accessors/read.ts b/{{cookiecutter.project_slug}}/frontend/src/store/admin/accessors/read.ts new file mode 100644 index 0000000..e46b843 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/admin/accessors/read.ts @@ -0,0 +1,10 @@ +import { getStoreAccessors } from 'typesafe-vuex'; +import { AdminState } from '../state'; +import { State } from '@/store/state'; +import { getters } from '../getters'; + +const { read } = getStoreAccessors(''); + +export const readAdminOneUser = read(getters.adminOneUser); +export const readAdminRoles = read(getters.adminRoles); +export const readAdminUsers = read(getters.adminUsers); diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/admin/actions.ts b/{{cookiecutter.project_slug}}/frontend/src/store/admin/actions.ts new file mode 100644 index 0000000..141ae1d --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/admin/actions.ts @@ -0,0 +1,64 @@ +import { api } from '@/api'; +import { ActionContext } from 'vuex'; +import { + commitSetUsers, + commitSetUser, + commitSetRoles, +} from './accessors/commit'; +import { IUserProfileCreate, IUserProfileUpdate } from '@/interfaces'; +import { State } from '../state'; +import { AdminState } from './state'; +import { dispatchCheckApiError, commitAddNotification, commitRemoveNotification } from '../main/accessors'; + +type MainContext = ActionContext; + +export const actions = { + async actionGetUsers(context: MainContext) { + try { + const response = await api.getUsers(context.rootState.main.token); + if (response) { + commitSetUsers(context, response.data); + } + } catch (error) { + await dispatchCheckApiError(context, error); + } + }, + async actionUpdateUser(context: MainContext, payload: { name: string, user: IUserProfileUpdate }) { + try { + const loadingNotification = { content: 'saving', showProgress: true }; + commitAddNotification(context, loadingNotification); + const response = (await Promise.all([ + api.updateUser(context.rootState.main.token, payload.name, payload.user), + await new Promise((resolve, reject) => setTimeout(() => resolve(), 500)), + ]))[0]; + commitSetUser(context, response.data); + commitRemoveNotification(context, loadingNotification); + commitAddNotification(context, {content: 'User successfully updated', color: 'success'}); + } catch (error) { + await dispatchCheckApiError(context, error); + } + }, + async actionCreateUser(context: MainContext, payload: IUserProfileCreate) { + try { + const loadingNotification = { content: 'saving', showProgress: true }; + commitAddNotification(context, loadingNotification); + const response = (await Promise.all([ + api.createUser(context.rootState.main.token, payload), + await new Promise((resolve, reject) => setTimeout(() => resolve(), 500)), + ]))[0]; + commitSetUser(context, response.data); + commitRemoveNotification(context, loadingNotification); + commitAddNotification(context, { content: 'User successfully created', color: 'success' }); + } catch (error) { + await dispatchCheckApiError(context, error); + } + }, + async actionGetRoles(context: MainContext) { + try { + const response = await api.getRoles(context.rootState.main.token); + commitSetRoles(context, response.data.roles); + } catch (error) { + await dispatchCheckApiError(context, error); + } + }, +}; diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/admin/getters.ts b/{{cookiecutter.project_slug}}/frontend/src/store/admin/getters.ts new file mode 100644 index 0000000..86c1c6b --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/admin/getters.ts @@ -0,0 +1,12 @@ +import { AdminState } from './state'; + +export const getters = { + adminUsers: (state: AdminState) => state.users, + adminRoles: (state: AdminState) => state.roles, + adminOneUser: (state: AdminState) => (name: string) => { + const filteredUsers = state.users.filter((user) => user.name === name); + if (filteredUsers.length > 0) { + return { ...filteredUsers[0] }; + } + }, +}; diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/admin/index.ts b/{{cookiecutter.project_slug}}/frontend/src/store/admin/index.ts new file mode 100644 index 0000000..fb29a1c --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/admin/index.ts @@ -0,0 +1,16 @@ +import { mutations } from './mutations'; +import { getters } from './getters'; +import { actions } from './actions'; +import { AdminState } from './state'; + +const defaultState: AdminState = { + users: [], + roles: [], +}; + +export const adminModule = { + state: defaultState, + mutations, + actions, + getters, +}; diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/admin/mutations.ts b/{{cookiecutter.project_slug}}/frontend/src/store/admin/mutations.ts new file mode 100644 index 0000000..3b0e846 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/admin/mutations.ts @@ -0,0 +1,16 @@ +import { IUserProfile } from '@/interfaces'; +import { AdminState } from './state'; + +export const mutations = { + setUsers(state: AdminState, payload: IUserProfile[]) { + state.users = payload; + }, + setUser(state: AdminState, payload: IUserProfile) { + const users = state.users.filter((user: IUserProfile) => user.name !== payload.name); + users.push(payload); + state.users = users; + }, + setRoles(state: AdminState, payload: string[]) { + state.roles = payload; + }, +}; diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/admin/state.ts b/{{cookiecutter.project_slug}}/frontend/src/store/admin/state.ts new file mode 100644 index 0000000..fc4ac8f --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/admin/state.ts @@ -0,0 +1,6 @@ +import { IUserProfile } from '@/interfaces'; + +export interface AdminState { + users: IUserProfile[]; + roles: string[]; +} diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/index.ts b/{{cookiecutter.project_slug}}/frontend/src/store/index.ts new file mode 100644 index 0000000..1089971 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/index.ts @@ -0,0 +1,19 @@ +import Vue from 'vue'; +import Vuex, { StoreOptions } from 'vuex'; + +import { mainModule } from './main'; +import { State } from './state'; +import { adminModule } from './admin'; + +Vue.use(Vuex); + +const storeOptions: StoreOptions = { + modules: { + main: mainModule, + admin: adminModule, + }, +}; + +export const store = new Vuex.Store(storeOptions); + +export default store; diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/main/accessors/commit.ts b/{{cookiecutter.project_slug}}/frontend/src/store/main/accessors/commit.ts new file mode 100644 index 0000000..3aafe76 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/main/accessors/commit.ts @@ -0,0 +1,15 @@ +import { getStoreAccessors } from 'typesafe-vuex'; +import { MainState } from '../state'; +import { State } from '@/store/state'; +import { mutations } from '../mutations'; + +const {commit} = getStoreAccessors(''); + +export const commitSetDashboardMiniDrawer = commit(mutations.setDashboardMiniDrawer); +export const commitSetDashboardShowDrawer = commit(mutations.setDashboardShowDrawer); +export const commitSetLoggedIn = commit(mutations.setLoggedIn); +export const commitSetLogInError = commit(mutations.setLogInError); +export const commitSetToken = commit(mutations.setToken); +export const commitSetUserProfile = commit(mutations.setUserProfile); +export const commitAddNotification = commit(mutations.addNotification); +export const commitRemoveNotification = commit(mutations.removeNotification); diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/main/accessors/dispatch.ts b/{{cookiecutter.project_slug}}/frontend/src/store/main/accessors/dispatch.ts new file mode 100644 index 0000000..d4d17f9 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/main/accessors/dispatch.ts @@ -0,0 +1,20 @@ +import { getStoreAccessors } from 'typesafe-vuex'; +import { MainState } from '../state'; +import { State } from '@/store/state'; +import { actions } from '../actions'; + +const {dispatch} = getStoreAccessors(''); + +export const dispatchCheckApiError = dispatch(actions.actionCheckApiError); +export const dispatchCheckLoggedIn = dispatch(actions.actionCheckLoggedIn); +export const dispatchGetUserProfile = dispatch(actions.actionGetUserProfile); +export const dispatchLogIn = dispatch(actions.actionLogIn); +export const dispatchLogOut = dispatch(actions.actionLogOut); +export const dispatchUserLogOut = dispatch(actions.actionUserLogOut); +export const dispatchRemoveLogIn = dispatch(actions.actionRemoveLogIn); +export const dispatchRouteLoggedIn = dispatch(actions.actionRouteLoggedIn); +export const dispatchRouteLogOut = dispatch(actions.actionRouteLogOut); +export const dispatchUpdateUserProfile = dispatch(actions.actionUpdateUserProfile); +export const dispatchRemoveNotification = dispatch(actions.removeNotification); +export const dispatchPasswordRecovery = dispatch(actions.passwordRecovery); +export const dispatchResetPassword = dispatch(actions.resetPassword); diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/main/accessors/index.ts b/{{cookiecutter.project_slug}}/frontend/src/store/main/accessors/index.ts new file mode 100644 index 0000000..5486b2e --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/main/accessors/index.ts @@ -0,0 +1,3 @@ +export * from './commit'; +export * from './dispatch'; +export * from './read'; diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/main/accessors/read.ts b/{{cookiecutter.project_slug}}/frontend/src/store/main/accessors/read.ts new file mode 100644 index 0000000..31f2ebc --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/main/accessors/read.ts @@ -0,0 +1,15 @@ +import { getStoreAccessors } from 'typesafe-vuex'; +import { MainState } from '../state'; +import { State } from '@/store/state'; +import { getters } from '../getters'; + +const {read} = getStoreAccessors(''); + +export const readDashboardMiniDrawer = read(getters.dashboardMiniDrawer); +export const readDashboardShowDrawer = read(getters.dashboardShowDrawer); +export const readHasAdminAccess = read(getters.hasAdminAccess); +export const readIsLoggedIn = read(getters.isLoggedIn); +export const readLoginError = read(getters.loginError); +export const readToken = read(getters.token); +export const readUserProfile = read(getters.userProfile); +export const readFirstNotification = read(getters.firstNotification); diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/main/actions.ts b/{{cookiecutter.project_slug}}/frontend/src/store/main/actions.ts new file mode 100644 index 0000000..81308e2 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/main/actions.ts @@ -0,0 +1,163 @@ +import { api } from '@/api'; +import { saveLocalToken, getLocalToken, removeLocalToken } from '@/utils'; +import router from '@/router'; +import { ActionContext } from 'vuex'; +import { + commitSetToken, + commitSetLoggedIn, + commitSetLogInError, + dispatchGetUserProfile, + dispatchRouteLoggedIn, + dispatchLogOut, + commitSetUserProfile, + dispatchCheckApiError, + dispatchRemoveLogIn, + dispatchRouteLogOut, + commitRemoveNotification, + commitAddNotification, +} from './accessors'; +import { AxiosError } from 'axios'; +import { IUserProfileCreate, IUserProfileUpdate } from '@/interfaces'; +import { State } from '../state'; +import { MainState, AppNotification } from './state'; + +type MainContext = ActionContext; + +export const actions = { + async actionLogIn(context: MainContext, payload: { username: string; password: string }) { + try { + const response = await api.logInGetToken(payload.username, payload.password); + const token = response.data.access_token; + if (token) { + saveLocalToken(token); + commitSetToken(context, token); + commitSetLoggedIn(context, true); + commitSetLogInError(context, false); + await dispatchGetUserProfile(context); + await dispatchRouteLoggedIn(context); + commitAddNotification(context, { content: 'Logged in', color: 'success' }); + } else { + await dispatchLogOut(context); + } + } catch (err) { + commitSetLogInError(context, true); + await dispatchLogOut(context); + } + }, + async actionGetUserProfile(context: MainContext) { + try { + const response = await api.getMe(context.state.token); + if (response.data) { + commitSetUserProfile(context, response.data); + } + } catch (error) { + await dispatchCheckApiError(context, error); + } + }, + async actionUpdateUserProfile(context: MainContext, payload) { + try { + const loadingNotification = { content: 'saving', showProgress: true }; + commitAddNotification(context, loadingNotification); + const response = (await Promise.all([ + api.updateMe(context.state.token, payload), + await new Promise((resolve, reject) => setTimeout(() => resolve(), 500)), + ]))[0]; + commitSetUserProfile(context, response.data); + commitRemoveNotification(context, loadingNotification); + commitAddNotification(context, { content: 'Profile successfully updated', color: 'success' }); + } catch (error) { + await dispatchCheckApiError(context, error); + } + }, + async actionCheckLoggedIn(context: MainContext) { + if (!context.state.isLoggedIn) { + let token = context.state.token; + if (!token) { + const localToken = getLocalToken(); + if (localToken) { + commitSetToken(context, localToken); + token = localToken; + } + } + if (token) { + try { + const response = await api.getMe(token); + commitSetLoggedIn(context, true); + commitSetUserProfile(context, response.data); + } catch (error) { + await dispatchRemoveLogIn(context); + } + } else { + await dispatchRemoveLogIn(context); + } + } + }, + async actionRemoveLogIn(context: MainContext) { + removeLocalToken(); + commitSetToken(context, ''); + commitSetLoggedIn(context, false); + }, + async actionLogOut(context: MainContext) { + await dispatchRemoveLogIn(context); + await dispatchRouteLogOut(context); + }, + async actionUserLogOut(context: MainContext) { + await dispatchLogOut(context); + commitAddNotification(context, { content: 'Logged out', color: 'success' }); + }, + actionRouteLogOut(context: MainContext) { + if (router.currentRoute.path !== '/login') { + router.push('/login'); + } + }, + async actionCheckApiError(context: MainContext, payload: AxiosError) { + if (payload.response!.status === 401) { + await dispatchLogOut(context); + } + }, + actionRouteLoggedIn(context: MainContext) { + if (router.currentRoute.path === '/login' || router.currentRoute.path === '/') { + router.push('/main'); + } + }, + async removeNotification(context: MainContext, payload: { notification: AppNotification, timeout: number }) { + return new Promise((resolve, reject) => { + setTimeout(() => { + commitRemoveNotification(context, payload.notification); + resolve(true); + }, payload.timeout); + }); + }, + async passwordRecovery(context: MainContext, payload: { username: string }) { + const loadingNotification = { content: 'Sending password recovery email', showProgress: true }; + try { + commitAddNotification(context, loadingNotification); + const response = (await Promise.all([ + api.passwordRecovery(payload.username), + await new Promise((resolve, reject) => setTimeout(() => resolve(), 500)), + ]))[0]; + commitRemoveNotification(context, loadingNotification); + commitAddNotification(context, { content: 'Password recovery email sent', color: 'success' }); + await dispatchLogOut(context); + } catch (error) { + commitRemoveNotification(context, loadingNotification); + commitAddNotification(context, { color: 'error', content: 'Incorrect username' }); + } + }, + async resetPassword(context: MainContext, payload: { password: string, token: string }) { + const loadingNotification = { content: 'Resetting password', showProgress: true }; + try { + commitAddNotification(context, loadingNotification); + const response = (await Promise.all([ + api.resetPassword(payload.password, payload.token), + await new Promise((resolve, reject) => setTimeout(() => resolve(), 500)), + ]))[0]; + commitRemoveNotification(context, loadingNotification); + commitAddNotification(context, { content: 'Password successfully reset', color: 'success' }); + await dispatchLogOut(context); + } catch (error) { + commitRemoveNotification(context, loadingNotification); + commitAddNotification(context, { color: 'error', content: 'Error resetting password' }); + } + }, +}; diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/main/getters.ts b/{{cookiecutter.project_slug}}/frontend/src/store/main/getters.ts new file mode 100644 index 0000000..ec61494 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/main/getters.ts @@ -0,0 +1,16 @@ +import { MainState } from './state'; + +export const getters = { + hasAdminAccess: (state: MainState) => { + return ( + state.userProfile && + state.userProfile.admin_roles.includes('superuser')); + }, + loginError: (state: MainState) => state.logInError, + dashboardShowDrawer: (state: MainState) => state.dashboardShowDrawer, + dashboardMiniDrawer: (state: MainState) => state.dashboardMiniDrawer, + userProfile: (state: MainState) => state.userProfile, + token: (state: MainState) => state.token, + isLoggedIn: (state: MainState) => state.isLoggedIn, + firstNotification: (state: MainState) => state.notifications.length > 0 && state.notifications[0], +}; diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/main/index.ts b/{{cookiecutter.project_slug}}/frontend/src/store/main/index.ts new file mode 100644 index 0000000..56ba1a0 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/main/index.ts @@ -0,0 +1,21 @@ +import { mutations } from './mutations'; +import { getters } from './getters'; +import { actions } from './actions'; +import { MainState } from './state'; + +const defaultState: MainState = { + isLoggedIn: null, + token: '', + logInError: false, + userProfile: null, + dashboardMiniDrawer: false, + dashboardShowDrawer: true, + notifications: [], +}; + +export const mainModule = { + state: defaultState, + mutations, + actions, + getters, +}; diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/main/mutations.ts b/{{cookiecutter.project_slug}}/frontend/src/store/main/mutations.ts new file mode 100644 index 0000000..9665c7f --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/main/mutations.ts @@ -0,0 +1,30 @@ +import { IUserProfile } from '@/interfaces'; +import { MainState, AppNotification } from './state'; + + +export const mutations = { + setToken(state: MainState, payload: string) { + state.token = payload; + }, + setLoggedIn(state: MainState, payload: boolean) { + state.isLoggedIn = payload; + }, + setLogInError(state: MainState, payload: boolean) { + state.logInError = payload; + }, + setUserProfile(state: MainState, payload: IUserProfile) { + state.userProfile = payload; + }, + setDashboardMiniDrawer(state: MainState, payload: boolean) { + state.dashboardMiniDrawer = payload; + }, + setDashboardShowDrawer(state: MainState, payload: boolean) { + state.dashboardShowDrawer = payload; + }, + addNotification(state: MainState, payload: AppNotification) { + state.notifications.push(payload); + }, + removeNotification(state: MainState, payload: AppNotification) { + state.notifications = state.notifications.filter((notification) => notification !== payload); + }, +}; diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/main/state.ts b/{{cookiecutter.project_slug}}/frontend/src/store/main/state.ts new file mode 100644 index 0000000..be24b63 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/main/state.ts @@ -0,0 +1,17 @@ +import { IUserProfile } from '@/interfaces'; + +export interface AppNotification { + content: string; + color?: string; + showProgress?: boolean; +} + +export interface MainState { + token: string; + isLoggedIn: boolean | null; + logInError: boolean; + userProfile: IUserProfile | null; + dashboardMiniDrawer: boolean; + dashboardShowDrawer: boolean; + notifications: AppNotification[]; +} diff --git a/{{cookiecutter.project_slug}}/frontend/src/store/state.ts b/{{cookiecutter.project_slug}}/frontend/src/store/state.ts new file mode 100644 index 0000000..ecec111 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/store/state.ts @@ -0,0 +1,5 @@ +import { MainState } from './main/state'; + +export interface State { + main: MainState; +} diff --git a/{{cookiecutter.project_slug}}/frontend/src/utils.ts b/{{cookiecutter.project_slug}}/frontend/src/utils.ts new file mode 100644 index 0000000..ade11b6 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/utils.ts @@ -0,0 +1,5 @@ +export const getLocalToken = () => localStorage.getItem('token'); + +export const saveLocalToken = (token: string) => localStorage.setItem('token', token); + +export const removeLocalToken = () => localStorage.removeItem('token'); diff --git a/{{cookiecutter.project_slug}}/frontend/src/views/Login.vue b/{{cookiecutter.project_slug}}/frontend/src/views/Login.vue new file mode 100644 index 0000000..eb54159 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/views/Login.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/{{cookiecutter.project_slug}}/frontend/src/views/PasswordRecovery.vue b/{{cookiecutter.project_slug}}/frontend/src/views/PasswordRecovery.vue new file mode 100644 index 0000000..70cde31 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/views/PasswordRecovery.vue @@ -0,0 +1,52 @@ + + + + + diff --git a/{{cookiecutter.project_slug}}/frontend/src/views/ResetPassword.vue b/{{cookiecutter.project_slug}}/frontend/src/views/ResetPassword.vue new file mode 100644 index 0000000..c9b24a6 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/views/ResetPassword.vue @@ -0,0 +1,88 @@ + + + diff --git a/{{cookiecutter.project_slug}}/frontend/src/views/main/Dashboard.vue b/{{cookiecutter.project_slug}}/frontend/src/views/main/Dashboard.vue new file mode 100644 index 0000000..22e1606 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/views/main/Dashboard.vue @@ -0,0 +1,35 @@ + + + diff --git a/{{cookiecutter.project_slug}}/frontend/src/views/main/Main.vue b/{{cookiecutter.project_slug}}/frontend/src/views/main/Main.vue new file mode 100644 index 0000000..562d5e1 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/views/main/Main.vue @@ -0,0 +1,187 @@ + + + diff --git a/{{cookiecutter.project_slug}}/frontend/src/views/main/Start.vue b/{{cookiecutter.project_slug}}/frontend/src/views/main/Start.vue new file mode 100644 index 0000000..3877ed8 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/views/main/Start.vue @@ -0,0 +1,37 @@ + + + diff --git a/{{cookiecutter.project_slug}}/frontend/src/views/main/admin/Admin.vue b/{{cookiecutter.project_slug}}/frontend/src/views/main/admin/Admin.vue new file mode 100644 index 0000000..f661535 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/views/main/admin/Admin.vue @@ -0,0 +1,33 @@ + + + diff --git a/{{cookiecutter.project_slug}}/frontend/src/views/main/admin/AdminUsers.vue b/{{cookiecutter.project_slug}}/frontend/src/views/main/admin/AdminUsers.vue new file mode 100644 index 0000000..e4b5f9b --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/views/main/admin/AdminUsers.vue @@ -0,0 +1,83 @@ + + + diff --git a/{{cookiecutter.project_slug}}/frontend/src/views/main/admin/CreateUser.vue b/{{cookiecutter.project_slug}}/frontend/src/views/main/admin/CreateUser.vue new file mode 100644 index 0000000..0a1cb49 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/views/main/admin/CreateUser.vue @@ -0,0 +1,110 @@ + + + diff --git a/{{cookiecutter.project_slug}}/frontend/src/views/main/admin/EditUser.vue b/{{cookiecutter.project_slug}}/frontend/src/views/main/admin/EditUser.vue new file mode 100644 index 0000000..acfcc89 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/views/main/admin/EditUser.vue @@ -0,0 +1,136 @@ + + + diff --git a/{{cookiecutter.project_slug}}/frontend/src/views/main/profile/UserProfile.vue b/{{cookiecutter.project_slug}}/frontend/src/views/main/profile/UserProfile.vue new file mode 100644 index 0000000..6781c1e --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/views/main/profile/UserProfile.vue @@ -0,0 +1,51 @@ + + + diff --git a/{{cookiecutter.project_slug}}/frontend/src/views/main/profile/UserProfileEdit.vue b/{{cookiecutter.project_slug}}/frontend/src/views/main/profile/UserProfileEdit.vue new file mode 100644 index 0000000..516911b --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/views/main/profile/UserProfileEdit.vue @@ -0,0 +1,79 @@ + + + diff --git a/{{cookiecutter.project_slug}}/frontend/src/views/main/profile/UserProfileEditPassword.vue b/{{cookiecutter.project_slug}}/frontend/src/views/main/profile/UserProfileEditPassword.vue new file mode 100644 index 0000000..4dab655 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/src/views/main/profile/UserProfileEditPassword.vue @@ -0,0 +1,82 @@ + + + diff --git a/{{cookiecutter.project_slug}}/frontend/tests/unit/upload-button.spec.ts b/{{cookiecutter.project_slug}}/frontend/tests/unit/upload-button.spec.ts new file mode 100644 index 0000000..b40eed7 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/tests/unit/upload-button.spec.ts @@ -0,0 +1,15 @@ +import { shallowMount } from '@vue/test-utils'; +import UploadButton from '@/components/UploadButton.vue'; +import '@/plugins/vuetify'; + +describe('UploadButton.vue', () => { + it('renders props.title when passed', () => { + const title = 'upload a file'; + const wrapper = shallowMount(UploadButton, { + slots: { + default: title, + }, + }); + expect(wrapper.text()).toMatch(title); + }); +}); diff --git a/{{cookiecutter.project_slug}}/frontend/tsconfig.json b/{{cookiecutter.project_slug}}/frontend/tsconfig.json new file mode 100644 index 0000000..88cfbc3 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/tsconfig.json @@ -0,0 +1,41 @@ +{ + "compilerOptions": { + "noImplicitAny": false, + "target": "esnext", + "module": "esnext", + "strict": true, + "jsx": "preserve", + "importHelpers": true, + "moduleResolution": "node", + "experimentalDecorators": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "sourceMap": true, + "baseUrl": ".", + "types": [ + "webpack-env", + "jest" + ], + "paths": { + "@/*": [ + "src/*" + ] + }, + "lib": [ + "esnext", + "dom", + "dom.iterable", + "scripthost" + ] + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx", + "src/**/*.vue", + "tests/**/*.ts", + "tests/**/*.tsx" + ], + "exclude": [ + "node_modules" + ] +} diff --git a/{{cookiecutter.project_slug}}/frontend/tslint.json b/{{cookiecutter.project_slug}}/frontend/tslint.json new file mode 100644 index 0000000..2b37e40 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/tslint.json @@ -0,0 +1,19 @@ +{ + "defaultSeverity": "warning", + "extends": [ + "tslint:recommended" + ], + "linterOptions": { + "exclude": [ + "node_modules/**" + ] + }, + "rules": { + "quotemark": [true, "single"], + "indent": [true, "spaces", 2], + "interface-name": false, + "ordered-imports": false, + "object-literal-sort-keys": false, + "no-consecutive-blank-lines": false + } +} diff --git a/{{cookiecutter.project_slug}}/frontend/vue.config.js b/{{cookiecutter.project_slug}}/frontend/vue.config.js new file mode 100644 index 0000000..1407134 --- /dev/null +++ b/{{cookiecutter.project_slug}}/frontend/vue.config.js @@ -0,0 +1,35 @@ +module.exports = { + // Fix Vuex-typescript in prod: https://github.com/istrib/vuex-typescript/issues/13#issuecomment-409869231 + configureWebpack: (config) => { + if (process.env.NODE_ENV === 'production') { + config.optimization.minimizer[0].options.terserOptions = Object.assign( + {}, + config.optimization.minimizer[0].options.terserOptions, + { + ecma: 5, + compress: { + keep_fnames: true, + }, + warnings: false, + mangle: { + keep_fnames: true, + }, + }, + ); + } + }, + chainWebpack: config => { + config.module + .rule('vue') + .use('vue-loader') + .loader('vue-loader') + .tap(options => Object.assign(options, { + transformAssetUrls: { + 'v-img': ['src', 'lazy-src'], + 'v-card': 'src', + 'v-card-media': 'src', + 'v-responsive': 'src', + } + })); + }, +} diff --git a/{{cookiecutter.project_slug}}/scripts/build-push.sh b/{{cookiecutter.project_slug}}/scripts/build-push.sh new file mode 100644 index 0000000..5fdcdd2 --- /dev/null +++ b/{{cookiecutter.project_slug}}/scripts/build-push.sh @@ -0,0 +1,10 @@ +#! /usr/bin/env sh + +# Exit in case of error +set -e + +TAG=${TAG} \ +FRONTEND_ENV=${FRONTEND_ENV-production} \ +source ./scripts/build.sh + +docker-compose -f docker-stack.yml push diff --git a/{{cookiecutter.project_slug}}/scripts/build.sh b/{{cookiecutter.project_slug}}/scripts/build.sh new file mode 100644 index 0000000..a76f3c2 --- /dev/null +++ b/{{cookiecutter.project_slug}}/scripts/build.sh @@ -0,0 +1,13 @@ +#! /usr/bin/env sh + +# Exit in case of error +set -e + +TAG=${TAG} \ +FRONTEND_ENV=${FRONTEND_ENV-production} \ +docker-compose \ +-f docker-compose.deploy.build.yml \ +-f docker-compose.deploy.images.yml \ +config > docker-stack.yml + +docker-compose -f docker-stack.yml build diff --git a/{{cookiecutter.project_slug}}/scripts/deploy.sh b/{{cookiecutter.project_slug}}/scripts/deploy.sh new file mode 100644 index 0000000..3e24f9e --- /dev/null +++ b/{{cookiecutter.project_slug}}/scripts/deploy.sh @@ -0,0 +1,24 @@ +#! /usr/bin/env sh + +# Exit in case of error +set -e + +DOMAIN=${DOMAIN} \ +TRAEFIK_TAG=${TRAEFIK_TAG} \ +STACK_NAME=${STACK_NAME} \ +TAG=${TAG} \ +docker-compose \ +-f docker-compose.shared.admin.yml \ +-f docker-compose.shared.base-images.yml \ +-f docker-compose.shared.depends.yml \ +-f docker-compose.shared.env.yml \ +-f docker-compose.deploy.command.yml \ +-f docker-compose.deploy.images.yml \ +-f docker-compose.deploy.labels.yml \ +-f docker-compose.deploy.networks.yml \ +-f docker-compose.deploy.volumes-placement.yml \ +config > docker-stack.yml + +docker-auto-labels docker-stack.yml + +docker stack deploy -c docker-stack.yml --with-registry-auth ${STACK_NAME} diff --git a/{{cookiecutter.project_slug}}/scripts/test-local.sh b/{{cookiecutter.project_slug}}/scripts/test-local.sh new file mode 100644 index 0000000..baccd71 --- /dev/null +++ b/{{cookiecutter.project_slug}}/scripts/test-local.sh @@ -0,0 +1,30 @@ +#! /usr/bin/env bash + +# Exit in case of error +set -e + +if [ $(uname -s) = "Linux" ]; then + echo "Remove __pycache__ files" + sudo find . -type d -name __pycache__ -exec rm -r {} \+ +fi + +docker-compose \ + -f docker-compose.test.yml \ + -f docker-compose.shared.admin.yml \ + -f docker-compose.shared.base-images.yml \ + -f docker-compose.shared.depends.yml \ + -f docker-compose.shared.env.yml \ + -f docker-compose.dev.build.yml \ + -f docker-compose.dev.env.yml \ + -f docker-compose.dev.labels.yml \ + -f docker-compose.dev.networks.yml \ + -f docker-compose.dev.ports.yml \ + -f docker-compose.dev.volumes.yml \ + config > docker-stack.yml + +# -f docker-compose.dev.command.yml \ + +docker-compose -f docker-stack.yml build +docker-compose -f docker-stack.yml down -v --remove-orphans # Remove possibly previous broken stacks left hanging after an error +docker-compose -f docker-stack.yml up -d +docker-compose -f docker-stack.yml exec -T backend-tests /tests-start.sh diff --git a/{{cookiecutter.project_slug}}/scripts/test.sh b/{{cookiecutter.project_slug}}/scripts/test.sh new file mode 100644 index 0000000..84f9cce --- /dev/null +++ b/{{cookiecutter.project_slug}}/scripts/test.sh @@ -0,0 +1,19 @@ +#! /usr/bin/env sh + +# Exit in case of error +set -e + +DOMAIN=backend \ +docker-compose \ +-f docker-compose.shared.base-images.yml \ +-f docker-compose.shared.env.yml \ +-f docker-compose.shared.depends.yml \ +-f docker-compose.deploy.build.yml \ +-f docker-compose.test.yml \ +config > docker-stack.yml + +docker-compose -f docker-stack.yml build +docker-compose -f docker-stack.yml down -v --remove-orphans # Remove possibly previous broken stacks left hanging after an error +docker-compose -f docker-stack.yml up -d +docker-compose -f docker-stack.yml exec -T backend-tests /tests-start.sh +docker-compose -f docker-stack.yml down -v --remove-orphans