From d4c91cda0fda5ee76b82174fd0ae9fdaed1a3bef Mon Sep 17 00:00:00 2001 From: AJ Slater Date: Mon, 24 Aug 2020 20:32:56 -0700 Subject: [PATCH 001/528] Alpha dev ci (#3) Ready for alpha release. Test artifacts and ci process looking good. --- .circleci/config.yml | 65 + .dockerignore | 1 - .gitignore | 3 + .gitmodules | 4 - .prettierignore | 10 +- .prettierrc.json | 5 + Dockerfile | 50 +- Dockerfile.build | 46 + NEWS | 14 +- README.md | 258 +- TODO | 5 - build-copy-artifacts.sh | 4 + build-dist-wheel.sh | 3 + build-runnable-image.sh | 4 + ci/archive-image.sh | 4 + ci/tag-and-push.sh | 9 + codex/__init__.py | 1 + {codex_api => codex}/admin.py | 37 +- codex/asgi.py | 11 +- {codex_api => codex/choices}/__init__.py | 0 .../src => codex}/choices/browserChoices.json | 7 +- {codex_api => codex}/choices/model.py | 0 .../src => codex}/choices/readerChoices.json | 0 {codex_api => codex}/choices/static.py | 4 +- codex/hypercorn.toml.default | 3 + .../choices => codex/librarian}/__init__.py | 0 codex/librarian/cover.py | 73 + {codex_api => codex}/librarian/crond.py | 12 +- {codex_api => codex}/librarian/daemon.py | 8 +- {codex_api => codex}/librarian/importer.py | 81 +- {codex_api => codex}/librarian/librariand.py | 107 +- {codex_api => codex}/librarian/queue.py | 25 +- {codex_api => codex}/librarian/scanner.py | 32 +- {codex_api => codex}/librarian/watcherd.py | 29 +- {codex_api => codex}/lifespan.py | 4 +- {codex_api => codex}/middleware.py | 0 codex/migrations/0001_init.py | 624 + .../migrations}/__init__.py | 0 {codex_api => codex}/models.py | 101 +- codex/run.py | 90 + .../serializers}/__init__.py | 0 {codex_api => codex}/serializers/auth.py | 12 +- {codex_api => codex}/serializers/browse.py | 14 +- {codex_api => codex}/serializers/metadata.py | 6 +- {codex_api => codex}/serializers/read.py | 18 +- {codex_api => codex}/serializers/vuetify.py | 0 codex/settings.py | 81 +- codex/signals.py | 19 + codex/static/admin/js/codex-admin.js | 12 - .../admin/css/codex-admin.css | 0 codex/static_src/admin/js/codex-admin.js | 14 + .../templates}/browserconfig.xml | 5 +- codex/templates/index.html | 63 + codex/templates/site.webmanifest | 19 + codex/urls.py | 32 +- codex_api/urls.py => codex/urls_api.py | 26 +- .../serializers => codex/views}/__init__.py | 0 {codex_api => codex}/views/auth.py | 27 +- {codex_api => codex}/views/browser.py | 239 +- codex/views/frontend.py | 22 + {codex_api => codex}/views/metadata.py | 18 +- {codex_api => codex}/views/mixins.py | 16 +- {codex_api => codex}/views/reader.py | 48 +- .../websocket.py => codex/websocket_server.py | 9 +- codex/wsgi.py | 4 +- codex_api/apps.py | 19 - codex_api/migrations/0001_initial.py | 338 - codex_api/static/404.png | Bin 162 -> 0 bytes codex_api/views/__init__.py | 0 codex_vue/.gitignore | 25 - codex_vue/.prettierignore | 3 - codex_vue/__init__.py | 0 codex_vue/apps.py | 5 - codex_vue/package.json | 72 - codex_vue/public/css/global.css | 0 codex_vue/public/index.html | 1 - codex_vue/public/index.html.webpack | 25 - codex_vue/src/components/book-cover.vue | 51 - codex_vue/src/public-path.js | 15 - codex_vue/static/favicon.ico | 1 - codex_vue/static/icons/favicon.ico | Bin 12014 -> 0 bytes codex_vue/static/icons/safari-pinned-tab.svg | 113 - codex_vue/static/icons/site.webmanifest | 19 - codex_vue/templates/codex_vue/index.html | 49 - codex_vue/tests.py | 4 - codex_vue/urls.py | 18 - codex_vue/views.py | 5 - codex_vue/vue.config.js | 15 - collectstatic.sh | 9 + dev-frontend.sh | 4 + dev-livereload.sh | 11 + dev-reverse-proxy.sh | 4 + dev-server-ttabs.sh | 13 + dev-server.sh | 12 - docker-compose-build.yaml | 12 + docker-compose.yaml | 7 +- docker-env | 6 + docker-run.sh | 3 - docker/nodesource/nodesource.buster.list | 1 + docker/nodesource/nodesource.focal.list | 1 + docker/nodesource/nodesource.gpg.key | 52 + fix-lint.sh | 5 + fix.sh | 5 - {codex_vue => frontend}/.browserslistrc | 0 {codex_vue => frontend}/.eslintrc.js | 0 frontend/.prettierignore | 4 + frontend/README.md | 11 + {codex_vue => frontend}/babel.config.js | 0 frontend/jest.config.js | 3 + {codex_vue => frontend}/package-lock.json | 12307 ++++++++++++---- frontend/package.json | 98 + .../public/css/normalize.css | 0 .../public/img/android-chrome-192x192.png | Bin 0 -> 9717 bytes .../public/img/android-chrome-512x512.png | Bin 0 -> 26920 bytes frontend/public/img/apple-touch-icon.png | Bin 0 -> 8928 bytes frontend/public/img/favicon-16x16.png | Bin 0 -> 510 bytes frontend/public/img/favicon-32x32.png | Bin 0 -> 1117 bytes frontend/public/img/favicon.ico | Bin 0 -> 10990 bytes frontend/public/img/mstile-150x150.png | Bin 0 -> 7220 bytes frontend/public/img/safari-pinned-tab.svg | 44 + frontend/public/img/webpack.css | 25 + frontend/public/index.html | 1 + {codex_vue => frontend}/public/robots.txt | 0 {codex_vue => frontend}/src/api/auth.js | 4 +- {codex_vue => frontend}/src/api/base.js | 5 +- {codex_vue => frontend}/src/api/browser.js | 27 +- {codex_vue => frontend}/src/api/metadata.js | 4 +- {codex_vue => frontend}/src/api/reader.js | 9 +- {codex_vue => frontend}/src/app.vue | 0 {codex_vue => frontend}/src/browser.vue | 37 +- frontend/src/choices/browserChoices.json | 30 + frontend/src/choices/readerChoices.json | 7 + .../src/components/auth-dialog.vue | 71 +- frontend/src/components/book-cover.vue | 86 + .../src/components/browse-card.vue | 76 +- .../src/components/browse-container-menu.vue | 67 + .../src/components/filter-sub-menu.vue | 2 +- .../src/components/metadata-autocomplete.vue | 2 +- .../src/components/metadata-combobox.vue | 0 .../src/components/metadata-dialog.vue | 1 + .../src/components/metadata-switch.vue | 1 - .../src/components/metadata-tags.vue | 0 .../src/components/metadata-text-field.vue | 0 .../src/components/metadata-textarea.vue | 0 .../src/components/placeholder-loading.vue | 20 + .../src/components/reader-comic-page.vue | 23 +- .../src/components/reader-nav-button.vue | 0 {codex_vue => frontend}/src/main.js | 4 +- {codex_vue => frontend}/src/not-found.vue | 0 .../src/plugins/vuetify.js | 0 {codex_vue => frontend}/src/reader.vue | 64 +- {codex_vue => frontend}/src/router/index.js | 9 +- {codex_vue => frontend}/src/router/route.js | 0 {codex_vue => frontend}/src/store/index.js | 0 .../src/store/modules/auth.js | 17 +- .../src/store/modules/browser.js | 95 +- .../src/store/modules/metadata.js | 0 .../src/store/modules/reader.js | 65 +- .../tests/unit/test_reader_nav_button.spec.js | 74 + frontend/vue.config.js | 18 + lint.sh | 8 +- nginx/README.md | 3 + nginx/nginx.yaml | 10 + pm | 1 + poetry.lock | 1141 +- pyproject.toml | 99 +- run-server.sh | 5 - run.sh | 5 + setup-dev.sh | 12 + setup.cfg | 7 +- setup.sh | 4 - strange.jpg | Bin 0 -> 75980 bytes superuser.sh | 8 - test.sh | 8 +- tests/README.md | 7 + tests/test_asgi.py | 13 + tests/test_models.py | 38 + tests/test_websocket.py | 6 + 178 files changed, 12503 insertions(+), 5544 deletions(-) create mode 100644 .circleci/config.yml delete mode 100644 .gitmodules create mode 100644 .prettierrc.json create mode 100644 Dockerfile.build delete mode 100644 TODO create mode 100755 build-copy-artifacts.sh create mode 100755 build-dist-wheel.sh create mode 100755 build-runnable-image.sh create mode 100755 ci/archive-image.sh create mode 100755 ci/tag-and-push.sh rename {codex_api => codex}/admin.py (80%) rename {codex_api => codex/choices}/__init__.py (100%) rename {codex_vue/src => codex}/choices/browserChoices.json (81%) rename {codex_api => codex}/choices/model.py (100%) rename {codex_vue/src => codex}/choices/readerChoices.json (100%) rename {codex_api => codex}/choices/static.py (94%) create mode 100644 codex/hypercorn.toml.default rename {codex_api/choices => codex/librarian}/__init__.py (100%) create mode 100644 codex/librarian/cover.py rename {codex_api => codex}/librarian/crond.py (75%) rename {codex_api => codex}/librarian/daemon.py (57%) rename {codex_api => codex}/librarian/importer.py (84%) rename {codex_api => codex}/librarian/librariand.py (53%) rename {codex_api => codex}/librarian/queue.py (78%) rename {codex_api => codex}/librarian/scanner.py (84%) rename {codex_api => codex}/librarian/watcherd.py (87%) rename {codex_api => codex}/lifespan.py (90%) rename {codex_api => codex}/middleware.py (100%) create mode 100644 codex/migrations/0001_init.py rename {codex_api/librarian => codex/migrations}/__init__.py (100%) rename {codex_api => codex}/models.py (82%) create mode 100755 codex/run.py rename {codex_api/migrations => codex/serializers}/__init__.py (100%) rename {codex_api => codex}/serializers/auth.py (79%) rename {codex_api => codex}/serializers/browse.py (93%) rename {codex_api => codex}/serializers/metadata.py (97%) rename {codex_api => codex}/serializers/read.py (74%) rename {codex_api => codex}/serializers/vuetify.py (100%) create mode 100644 codex/signals.py delete mode 100644 codex/static/admin/js/codex-admin.js rename codex/{static => static_src}/admin/css/codex-admin.css (100%) create mode 100644 codex/static_src/admin/js/codex-admin.js rename {codex_vue/static/icons => codex/templates}/browserconfig.xml (51%) create mode 100644 codex/templates/index.html create mode 100644 codex/templates/site.webmanifest rename codex_api/urls.py => codex/urls_api.py (73%) rename {codex_api/serializers => codex/views}/__init__.py (100%) rename {codex_api => codex}/views/auth.py (85%) rename {codex_api => codex}/views/browser.py (72%) create mode 100644 codex/views/frontend.py rename {codex_api => codex}/views/metadata.py (84%) rename {codex_api => codex}/views/mixins.py (92%) rename {codex_api => codex}/views/reader.py (82%) rename codex_api/websocket.py => codex/websocket_server.py (92%) delete mode 100644 codex_api/apps.py delete mode 100644 codex_api/migrations/0001_initial.py delete mode 100644 codex_api/static/404.png delete mode 100644 codex_api/views/__init__.py delete mode 100644 codex_vue/.gitignore delete mode 100644 codex_vue/.prettierignore delete mode 100644 codex_vue/__init__.py delete mode 100644 codex_vue/apps.py delete mode 100644 codex_vue/package.json delete mode 100644 codex_vue/public/css/global.css delete mode 120000 codex_vue/public/index.html delete mode 100644 codex_vue/public/index.html.webpack delete mode 100644 codex_vue/src/components/book-cover.vue delete mode 100644 codex_vue/src/public-path.js delete mode 120000 codex_vue/static/favicon.ico delete mode 100644 codex_vue/static/icons/favicon.ico delete mode 100644 codex_vue/static/icons/safari-pinned-tab.svg delete mode 100644 codex_vue/static/icons/site.webmanifest delete mode 100644 codex_vue/templates/codex_vue/index.html delete mode 100644 codex_vue/tests.py delete mode 100644 codex_vue/urls.py delete mode 100644 codex_vue/views.py delete mode 100644 codex_vue/vue.config.js create mode 100755 collectstatic.sh create mode 100755 dev-frontend.sh create mode 100755 dev-livereload.sh create mode 100755 dev-reverse-proxy.sh create mode 100755 dev-server-ttabs.sh delete mode 100755 dev-server.sh create mode 100644 docker-compose-build.yaml create mode 100644 docker-env delete mode 100755 docker-run.sh create mode 100644 docker/nodesource/nodesource.buster.list create mode 100644 docker/nodesource/nodesource.focal.list create mode 100644 docker/nodesource/nodesource.gpg.key create mode 100755 fix-lint.sh delete mode 100755 fix.sh rename {codex_vue => frontend}/.browserslistrc (100%) rename {codex_vue => frontend}/.eslintrc.js (100%) create mode 100644 frontend/.prettierignore create mode 100644 frontend/README.md rename {codex_vue => frontend}/babel.config.js (100%) create mode 100644 frontend/jest.config.js rename {codex_vue => frontend}/package-lock.json (63%) create mode 100644 frontend/package.json rename {codex_vue => frontend}/public/css/normalize.css (100%) create mode 100644 frontend/public/img/android-chrome-192x192.png create mode 100644 frontend/public/img/android-chrome-512x512.png create mode 100644 frontend/public/img/apple-touch-icon.png create mode 100644 frontend/public/img/favicon-16x16.png create mode 100644 frontend/public/img/favicon-32x32.png create mode 100644 frontend/public/img/favicon.ico create mode 100644 frontend/public/img/mstile-150x150.png create mode 100644 frontend/public/img/safari-pinned-tab.svg create mode 100644 frontend/public/img/webpack.css create mode 100644 frontend/public/index.html rename {codex_vue => frontend}/public/robots.txt (100%) rename {codex_vue => frontend}/src/api/auth.js (88%) rename {codex_vue => frontend}/src/api/base.js (71%) rename {codex_vue => frontend}/src/api/browser.js (53%) rename {codex_vue => frontend}/src/api/metadata.js (69%) rename {codex_vue => frontend}/src/api/reader.js (75%) rename {codex_vue => frontend}/src/app.vue (100%) rename {codex_vue => frontend}/src/browser.vue (94%) create mode 100644 frontend/src/choices/browserChoices.json create mode 100644 frontend/src/choices/readerChoices.json rename {codex_vue => frontend}/src/components/auth-dialog.vue (72%) create mode 100644 frontend/src/components/book-cover.vue rename {codex_vue => frontend}/src/components/browse-card.vue (77%) create mode 100644 frontend/src/components/browse-container-menu.vue rename {codex_vue => frontend}/src/components/filter-sub-menu.vue (98%) rename {codex_vue => frontend}/src/components/metadata-autocomplete.vue (96%) rename {codex_vue => frontend}/src/components/metadata-combobox.vue (100%) rename {codex_vue => frontend}/src/components/metadata-dialog.vue (99%) rename {codex_vue => frontend}/src/components/metadata-switch.vue (95%) rename {codex_vue => frontend}/src/components/metadata-tags.vue (100%) rename {codex_vue => frontend}/src/components/metadata-text-field.vue (100%) rename {codex_vue => frontend}/src/components/metadata-textarea.vue (100%) create mode 100644 frontend/src/components/placeholder-loading.vue rename {codex_vue => frontend}/src/components/reader-comic-page.vue (77%) rename {codex_vue => frontend}/src/components/reader-nav-button.vue (100%) rename {codex_vue => frontend}/src/main.js (84%) rename {codex_vue => frontend}/src/not-found.vue (100%) rename {codex_vue => frontend}/src/plugins/vuetify.js (100%) rename {codex_vue => frontend}/src/reader.vue (88%) rename {codex_vue => frontend}/src/router/index.js (77%) rename {codex_vue => frontend}/src/router/route.js (100%) rename {codex_vue => frontend}/src/store/index.js (100%) rename {codex_vue => frontend}/src/store/modules/auth.js (81%) rename {codex_vue => frontend}/src/store/modules/browser.js (80%) rename {codex_vue => frontend}/src/store/modules/metadata.js (100%) rename {codex_vue => frontend}/src/store/modules/reader.js (72%) create mode 100644 frontend/tests/unit/test_reader_nav_button.spec.js create mode 100644 frontend/vue.config.js create mode 100644 nginx/README.md create mode 100644 nginx/nginx.yaml delete mode 100755 run-server.sh create mode 100755 run.sh create mode 100755 setup-dev.sh delete mode 100755 setup.sh create mode 100644 strange.jpg delete mode 100755 superuser.sh create mode 100644 tests/README.md create mode 100644 tests/test_asgi.py create mode 100644 tests/test_models.py create mode 100644 tests/test_websocket.py diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000..80f4a4026 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,65 @@ +executors: + docker-publisher: + machine: true +jobs: + build: + executor: docker-publisher + steps: + - checkout + - run: + command: ./build-dist-wheel.sh + name: Build Python Wheel + - store_test_results: + path: test-results/pytest + - store_artifacts: + path: test-results/coverage + - run: + command: ./build-runnable-image.sh + name: Build Runnable Docker Image + - run: + command: ./ci/archive-image.sh ./<< pipeline.parameters.image_archive >> + name: Archive Docker image + - persist_to_workspace: + paths: + - ./<< pipeline.parameters.image_archive >> + - ./dist + - ./docker-env + - ./ci/tag-and-push.sh + root: . + deploy: + executor: docker-publisher + steps: + - attach_workspace: + at: . + - run: + command: docker load -i "./<< pipeline.parameters.image_archive >>" + name: Load archive Docker image + - run: + command: ./ci/tag-and-push.sh + name: Publish Docker Image to Docker Hub +parameters: + image_archive: + default: image.tar + type: string +version: 2.1 +workflows: + main: + jobs: + - build: + filters: + branches: + only: + - release + - develop + - circleci + - /.*-ci/ + - deploy: + filters: + branches: + only: + - release + - circleci + requires: + - build + version: 2.1 + diff --git a/.dockerignore b/.dockerignore index 3685399ff..ec7160535 100644 --- a/.dockerignore +++ b/.dockerignore @@ -14,7 +14,6 @@ Dockerfile* MANIFEST NEWS __pycache__ -build*.sh docker-compose* monkeytype.sqlite3 test-results diff --git a/.gitignore b/.gitignore index ce4d20425..e78ec6bc4 100644 --- a/.gitignore +++ b/.gitignore @@ -143,11 +143,14 @@ jspm_packages/ .DS_Store build config +codex/static_build/ +codex/static_root/ dist db.sqlite3 monkeytype.sqlite3 node_modules test-results +webpack-stats.json ############################## # Until comicbox is released # ############################## diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 5f1f0c0e3..000000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "django"] - path = django - url = https://github.com/django/django.git - depth = 1 diff --git a/.prettierignore b/.prettierignore index 2b72b7a9c..4781c7ce9 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,9 +1,11 @@ +.circleci .mypy_cache .pytest_cache __pycache__ +codex/static_build +codex/static_root +frontend/dist +frontend/public/css/normalize.css templates -dist -webpack-stats.json -codex_vue/public/index.html -/static +static_prod /test-results diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 000000000..a955c5383 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,5 @@ +{ + "trailingComma": "es5", + "arrowParens": "always", + "tabWidth": 2 +} diff --git a/Dockerfile b/Dockerfile index f722b8f07..aeb53977a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,42 +1,42 @@ -FROM python:alpine +ARG BASE_VERSION +FROM ajslater/python-alpine:$BASE_VERSION AS codex-install -# TODO audit these to see if we really need them all -RUN \ -echo "**** install system packages ****" && \ +RUN echo "**** install system wheel building packages ****" && \ apk add --no-cache \ bsd-compat-headers \ build-base \ libffi-dev \ - nodejs \ - npm \ + libwebp-dev \ openssl-dev \ yaml-dev \ jpeg-dev \ zlib-dev -RUN \ - echo "**** install poetry ****" && \ - pip3 install --no-cache-dir -U poetry +RUN pip3 install wheel +# TODO replace with: +# RUN pip3 install codex +COPY dist/*.whl /tmp/ +RUN pip3 wheel /tmp/*.whl --wheel-dir=/wheels -WORKDIR /app -RUN echo "**** copying source ****" -COPY . . -RUN echo "**** install api ****" && \ - poetry install --no-dev +FROM ajslater/python-alpine:$BASE_VERSION +LABEL version python${BASE_VERSION}_codex-${PKG_VERSION} -WORKDIR /app/codex_vue -RUN echo "**** install ui packages ***" && \ - npm install && \ - npm install --dev - -RUN echo "**** build vue ui ***" && \ - npm run build +RUN echo "*** install system runtime packages ***" && \ + apk add --no-cache \ + libffi \ + libwebp \ + openssl \ + yaml \ + jpeg \ + zlib \ + unrar -WORKDIR /app +RUN echo "*** install python wheels ***" +COPY --from=codex-install /wheels /wheels -# TODO copy installed app and install non-dev libs for multi-stage build +RUN pip3 install --no-index --find-links=/wheels /wheels/codex*.whl VOLUME /comics VOLUME /config -EXPOSE 8000 -CMD ["./docker-run.sh"] +EXPOSE 9810 +CMD ["/usr/local/bin/codex"] diff --git a/Dockerfile.build b/Dockerfile.build new file mode 100644 index 000000000..2e9ac9636 --- /dev/null +++ b/Dockerfile.build @@ -0,0 +1,46 @@ +FROM ajslater/codex-builder:focal_1.0.0-db5d3fe + +ARG DEBIAN_FRONTEND=noninteractive + +############# +# APP SETUP # +############# + +RUN echo "**** copying source for dev build ****" +COPY . . + +RUN ./setup-dev.sh + +######## +# TEST # +######## + +WORKDIR /app +RUN echo "*** run lint ***" +RUN ./lint.sh + +RUN echo "*** run tests ***" +RUN ./test.sh + +######### +# BUILD # +######### + +WORKDIR /app/frontend + +RUN echo "*** build frontend ***" && \ + rm -rf ../codex/static_build && \ + npm run build + +WORKDIR /app +RUN echo "*** collect static resources in one place ***" && \ + ./collectstatic.sh + +# XXX poetry auto-excludes anything in gitignore. Dirty hack around that. +RUN echo "*** build and package application ***" && \ + sed -i "s/.*static_root.*//" .gitignore && \ + poetry build + +VOLUME /dist +VOLUME /test-results +CMD ["./build-copy-artifacts.sh"] diff --git a/NEWS b/NEWS index babe73381..d04d54ab3 100644 --- a/NEWS +++ b/NEWS @@ -1,17 +1,15 @@ +v0.5.0 +* Productionized alpha release + v0.4.0 * Polished VueJS frontend v0.3.0 -* Single Page Frontend without much styling. - -v0.2.1 -* Progress bar for browse containers & folders -* Cleanups and bugfixing +* Single Page VueJS frontend PoC without much styling v0.2.0 -* Working application with all initial features. -* A page by page front end. -* Zero styling. Looks like craiglist. +* Working application with all initial features +* Django frontend v0.1.0 * Proof of concept. diff --git a/README.md b/README.md index 2dfc82f8d..ff1e594bf 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,242 @@ +# Codex + Codex is a comic archive browser and reader. -# Important features: +## Features + +- A web server, not a desktop or mobile app. +- Per user bookmarking. +- Filter and sort on comic metadata and unread status per user. +- Watches the filesystem and automatically imports new or changed comics. + +## State of Development + +Codex is in alpha test. It has not received widespread testing. +[Please file bug reports on GitHub.](https://github.com/ajslater/codex/issues) It is still possible that the data model might change enough that subsequent versions might require a database reset. + +## Demonstration + +You may browse a [live demo server](https://codex.sl8r.net/) on a very small VPS, with no CDN. Caching is likely unsufficient for heavy load at this time. It would probably crash if it got swarmed right now. + +## Install Codex + +### Docker + +All dependancies bundled in the official [Docker Image](https://hub.docker.com/r/ajslater/codex). + +### Install with pip + +#### Wheel Build Dependencies + +You'll need to install these system dependencies before installing codex. + +##### MacOS + +```sh +brew install libffi jpeg openssl libyaml libzip python +``` + +##### Linux + +###### Debian based (e.g. Ubuntu) + +```sh +apt install build-essential libffi-dev libjpeg-dev libssl-dev libyaml-dev python3-pip zlib1g-dev +``` + +###### Alpine + +```sh +apk add bsd-compat-headers build-base libffi-dev openssl-dev yaml-dev jpeg-dev zlib-dev +``` + +#### Install unrar Runtime Dependancy + +Codex requires unrar to read cbr formatted comic archives. + +##### Linux + +[How to install unrar in Linux](https://www.unixtutorial.org/how-to-install-unrar-in-linux/) + +##### MacOS + +```sh +brew install unrar +``` + +#### Install Codex with pip + +Finally, you may install codex with pip + +```sh +pip3 install codex +``` + +## Run Codex + +pip should install the codex binary on your path. Run + +```sh +codex +``` + +and then navigate to [http://localhost:9810/](http://localhost:9810/) + +### Administration + +#### Change the Admin password + +The first thing you need to do is to log in as an Administrator. + +- Log in with the three dots menu in the upper right of the browse view. The default administator username/password is admin/admin. +- Navigate to the Admin Panel by selecting it from under the three dots menu after you have logged in. +- Navigate to the Users panel. +- Select the `admin` user. +- Change the admin password using the tiny "this form" link in the password section. +- You may also change the admin user's name or anything else. + +#### Adding Libraries + +The first thing you need to do is to log in as an Administrator and add one or more comic libraries. + +- Log in with any superuser (such as the default adimin account) using the three dots menu in the upper right of the browse view. +- Navigate to the Admin Panel by selecting it from under the three dots menu after you have logged in. +- Navigate to the Codex API Librarys (sic) on the Admin Panel +- Add a Library with the "ADD LIBRARY +" button in the upper right. + -- A Library is just a path where Codex can recursively search for comic archives. + -- Codex will try to import comics from a Library immediately. +- Navigate back to the browse view by clicking the "view site" link in the upper right of the Admin Panel. +- Wait for comics to appear. It may take some time to import large comic libraries and Codex will only issue a browser refresh websocket notification when the entire library has loaded. Check the console if you want to be assured its doing something. + +#### Admin Flags + +##### Disable Registration + +By default users bookmarks and preferenrces are saved in an anonymous brower session. But users can create a username & password to save their bookmarks in between browsers. You may disable this ability in the Admin Flags section of the Admin Panel. + +##### Disable Folder View + +By default, codex provides a "Folder View" which mimics the directory heirarchy of the libraries that you've added to Codex. If you wish to disable this view for all users, you may do so in the Admin Flags. The database style browser view is always available. + +##### Reset the admin password. + +If you forget all your superuser passwords, you may restore the original default admin account by running codex with the `CODEX_RESET_ADMIN` environment variable set. + +```sh +CODEX_RESET_ADMIN=1 codex +``` + +or if using docker: + +```sh +docker run -e CODEX_RESET_ADMIN=1 codex +``` + +## Configure Codex + +### Config Dir + +The default config directory is named `config/` directly under the working directory you run codex from. You may specificy an alternate config directory with the environment variable `CODEX_CONFIG_DIR`. + +The config directory contains a hypercorn config `hypercorn.toml` where you can specify ports and bind addresses. If no `hypercorn.toml` is present a default one is copied to that directory on startup. The default port is 9810. + +The config directory also holds the main sqlite database, a django cache and comic book cover thumbnails generated when comics are imported. Reimport a comic or an entire library to regenereate these cover thumbnails. + +### Reverse Proxy + +[nginx](https://nginx.org/) is often used as a TLS terminator and subpath proxy. + +Here's an example nginx config with a subpath named '/codex'. + +```nginx +proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $server_name; + proxy_set_header X-Forwarded-Port $server_port; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Scheme $scheme; + + # WS + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade" + + # This example uses a docker container named 'codex' at sub-path /codex + # Use a valid IP or resolvable host name for other configurations. + location /codex { + proxy_pass http://codex:9810; + } +``` + +Specify a reverse proxy sub path (if you have one) in the config/hypercorn.toml + +```toml +root_path = "/codex" + +``` + +#### Nginx Reverse Proxy 502 when container is refreshed. + +Nginx requires a special trick to refresh dns when linked Docker containers +are recreated. See this [nginx with dynamix upstreams](https://tenzer.dk/nginx-with-dynamic-upstreams/) article. + +## Using Codex + +### Sessions & Accounts + +Once your administrator has added some comic libraries, you may browse and read comics. Codex will remember your preferences, bookmarks and progress in the browser session. Sessions last 60 days at which point they are destroyed. +To preserve these settings across browsers and after sessions expire, you may register an account with a username and password. +You will have to contact your administrator to reset your password if you forget it. + +## Codex Roadmap + +### Alpha Test + +- Fix bugs that I haven't found in my private testing + +### Next Up + +- Edit & write metadata for one comic at a time. +- Add more Filters & Sort options (e.g. filter by story_arc, location) +- Fix Admin Pages Styling to match the rest of Codex. +- Upgrade Vue to version 3 + +## Out of Scope -- Per user bookmarking -- Filter and sort by metadata +- No intention of making this an eBook reader like [Ubooquity](https://vaemendis.net/ubooquity/). +- Not interested in this becoming a sophisticated comic manager like [Mylar](https://github.com/mylar3/mylar3) +- Unsure if I want to implement a mass tag editor. -# Roadmap: +## Alternatives to Codex -## 0.2 +- [Komga](https://komga.org/) has light metadata editing and full text search of metadata. +- [Ubooquity](https://vaemendis.net/ubooquity/) is a good looking comic webserver. It also reads eBooks. -### Library +## Develop Codex -- Filesystem watching with auto-import -- Scheduled rescans +Codex is a Django Python webserver with a VueJS front end. This is my first ever Javascript frontend. In retrospect I wish I'd known about FastAPI when I started, that looks nice. But I'm pretty satisfied with VueJS. -### Browser +`/codex/codex/` is the main django app which provides the webserver and database. -- View metadata -- Collapse group views -- More filters -- More sorts -- Number of descendant comics -- Pagination +`/codex/frontend/` is where the vuejs frontend lives. -### Reader +`/codex/setup-dev.sh` will install development dependancies. -- Touch controls -- Fit to Height -- Go to Page -- Progress Bar -- Hotkeys +`/codex/dev-server-ttabs.sh` will run the three or four different servers reccomended for development in terminal tabs. -### Admin Settings +`/codex/run.sh` runs the main Django server. Set the `DEV` environment variable to activea development and debug mode: `DEV=1 ./run.sh`. This also lets you run the server without collecting static files for production and with a hot reloading frontend. -- Reverse Proxy support -- Disable File View +### Links -## 0.3 +- [Docker Image](https://hub.docker.com/r/ajslater/codex) +- [PyPi Package](https://pypi.org/project/codex/) +- [GitHub Project](https://github.com/ajslater/codex/) -- Styling -- Two Page Spread for Reader -- Fancy Filtering -- More sorts +## Special Thanks -## Alpha Release? +Thanks to [Aurélien Mazurie](https://pypi.org/user/ajmazurie/) for allowing me to use the PyPi name 'codex'. -## 0.4+ +## Enjoy! -- Mass Metadata Editor -- Full Text Search -- Caching? +![These simple people have managed to tap into the spiritual forces that mystics and yogis spend literal lifetimes seeking. I feel... ...I feel...](strange.jpg) diff --git a/TODO b/TODO deleted file mode 100644 index 693fab272..000000000 --- a/TODO +++ /dev/null @@ -1,5 +0,0 @@ -Mark missing is unanswered question - -# Once comicbox is released -depend on real comicbox -remove hacked comicbox dependancies diff --git a/build-copy-artifacts.sh b/build-copy-artifacts.sh new file mode 100755 index 000000000..de2e135f8 --- /dev/null +++ b/build-copy-artifacts.sh @@ -0,0 +1,4 @@ +#!/bin/sh +set -eu +cp -a /app/dist/* /dist/ +cp -a /app/test-results/* /test-results/ diff --git a/build-dist-wheel.sh b/build-dist-wheel.sh new file mode 100755 index 000000000..6381f057b --- /dev/null +++ b/build-dist-wheel.sh @@ -0,0 +1,3 @@ +#!/bin/sh +# Build pip installable wheel and sdist files from Dockerfile.build +docker-compose -f docker-compose-build.yaml up --build diff --git a/build-runnable-image.sh b/build-runnable-image.sh new file mode 100755 index 000000000..32f1125d0 --- /dev/null +++ b/build-runnable-image.sh @@ -0,0 +1,4 @@ +#!/bin/sh +# Build a codex docker image suitable for running from Dockerfile +. ./docker-env +docker build -t "$IMAGE" --build-arg "BASE_VERSION=$BASE_VERSION" --build-arg "PKG_VERSION=$PKG_VERSION" . diff --git a/ci/archive-image.sh b/ci/archive-image.sh new file mode 100755 index 000000000..b2007fafd --- /dev/null +++ b/ci/archive-image.sh @@ -0,0 +1,4 @@ +#!/bin/bash +set -euo pipefail +source ./docker-env +docker save -o "$1" "$IMAGE" diff --git a/ci/tag-and-push.sh b/ci/tag-and-push.sh new file mode 100755 index 000000000..3b4eb5471 --- /dev/null +++ b/ci/tag-and-push.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -euo pipefail +source ./docker-env +VERSION=python${BASE_VERSION}_mylar-${PKG_VERSION} +TAG=$VERSION-$(echo "$CIRCLE_SHA1" | head -c 7) +docker tag "$IMAGE" "$IMAGE:$TAG" +docker tag "$IMAGE" "$IMAGE:latest" +docker login -u="$DOCKER_USER" -p="$DOCKER_PASS" +docker push "$REPO" diff --git a/codex/__init__.py b/codex/__init__.py index e69de29bb..e6e0e8350 100644 --- a/codex/__init__.py +++ b/codex/__init__.py @@ -0,0 +1 @@ +import codex.signals # noqa F401 diff --git a/codex_api/admin.py b/codex/admin.py similarity index 80% rename from codex_api/admin.py rename to codex/admin.py index 5c1959c0a..a5966fa1a 100644 --- a/codex_api/admin.py +++ b/codex/admin.py @@ -4,12 +4,14 @@ from django.contrib.admin import ModelAdmin from django.contrib.admin import register -from codex_api.librarian.queue import QUEUE -from codex_api.librarian.queue import LibraryChangedTask -from codex_api.librarian.queue import ScanRootTask -from codex_api.librarian.queue import WatchLibraryTask -from codex_api.models import AdminFlag -from codex_api.models import Library +from codex.librarian.cover import purge_all_covers +from codex.librarian.queue import QUEUE +from codex.librarian.queue import LibraryChangedTask +from codex.librarian.queue import ScannerCronTask +from codex.librarian.queue import ScanRootTask +from codex.librarian.queue import WatcherCronTask +from codex.models import AdminFlag +from codex.models import Library LOG = logging.getLogger(__name__) @@ -40,7 +42,9 @@ class AdminLibrary(ModelAdmin): "enable_scan_cron", "scan_frequency", "scan_in_progress", - # TODO can't submit anything if this doesn't have a value + # XXX can't submit anything at all if this doesn't have a value. + # I mark this disabled and readonly with javascript. Ugly. + # This a django bug. "last_scan", ) readonly_fields = ("last_scan",) @@ -66,12 +70,9 @@ def force_scan(self, request, queryset): force_scan.short_description = "Rescan all comics" def _on_change(self, obj, created=False): - task = WatchLibraryTask(obj.pk, obj.enable_watch) - QUEUE.put(task) - if created: - task = ScanRootTask(obj.pk, False) - QUEUE.put(task) + QUEUE.put(ScannerCronTask(sleep=1)) + QUEUE.put(WatcherCronTask(sleep=1)) def save_model(self, request, obj, form, change): """Trigger watching and scanning on update or creation.""" @@ -82,16 +83,18 @@ def save_model(self, request, obj, form, change): def delete_model(self, request, obj): """Stop watching on delete.""" - task = WatchLibraryTask(obj.pk, False) - QUEUE.put(task) + purge_all_covers(obj) super().delete_model(request, obj) + QUEUE.put(WatcherCronTask(sleep=1)) + QUEUE.put(LibraryChangedTask()) def delete_queryset(self, request, queryset): """Bulk delete.""" for obj in queryset: - task = WatchLibraryTask(obj.pk, False) - QUEUE.put(task) + purge_all_covers(obj) super().delete_queryset(request, queryset) + QUEUE.put(WatcherCronTask(sleep=1)) + QUEUE.put(LibraryChangedTask()) def save_formset(self, request, form, formset, change): """Bulk update.""" @@ -134,7 +137,7 @@ def save_formset(self, request, form, formset, change): def _on_change(self): """Signal UI that its out of date.""" - # XXX too heavy handed. + # Heavy handed refresh everything, but simple. # Folder View could only change the group view and let the ui decide # Registration only needs to change the enable flag task = LibraryChangedTask() diff --git a/codex/asgi.py b/codex/asgi.py index 8285386fa..0b6fb231f 100644 --- a/codex/asgi.py +++ b/codex/asgi.py @@ -8,11 +8,15 @@ """ import os +from logging import getLogger + from django.core.asgi import get_asgi_application -from codex_api.lifespan import lifespan_application -from codex_api.websocket import websocket_application +from codex.lifespan import lifespan_application +from codex.websocket_server import websocket_application + +LOG = getLogger() os.environ.setdefault("DJANGO_SETTINGS_MODULE", "codex.settings") # os.environ['PYTHONASYNCIODEBUG'] = "1" @@ -22,6 +26,9 @@ async def application(scope, receive, send): """Provide different application for different protocols.""" + LOG.debug( + f"{scope.get('client', [None])[0]} {scope.get('type')} {scope.get('path')}" + ) if scope["type"] == "http": await django_application(scope, receive, send) elif scope["type"] == "websocket": diff --git a/codex_api/__init__.py b/codex/choices/__init__.py similarity index 100% rename from codex_api/__init__.py rename to codex/choices/__init__.py diff --git a/codex_vue/src/choices/browserChoices.json b/codex/choices/browserChoices.json similarity index 81% rename from codex_vue/src/choices/browserChoices.json rename to codex/choices/browserChoices.json index 815860ff0..cb855a852 100644 --- a/codex_vue/src/choices/browserChoices.json +++ b/codex/choices/browserChoices.json @@ -9,13 +9,14 @@ { "text": "Imprints", "value": "p", "default": true }, { "text": "Series", "value": "i" }, { "text": "Volumes", "value": "s" }, + { "text": "Comics", "value": "v" }, { "text": "Folder View", "value": "f" } ], "settingsGroup": [ - { "text": "Publishers", "value": "p", "default": true}, - { "text": "Imprints", "value": "i"}, + { "text": "Publishers", "value": "p", "default": true }, + { "text": "Imprints", "value": "i" }, { "text": "Series", "value": "s" }, - { "text": "Volumes", "value": "v", "default": true} + { "text": "Volumes", "value": "v", "default": true } ], "sort": [ { "text": "Name", "value": "sort_name", "default": true }, diff --git a/codex_api/choices/model.py b/codex/choices/model.py similarity index 100% rename from codex_api/choices/model.py rename to codex/choices/model.py diff --git a/codex_vue/src/choices/readerChoices.json b/codex/choices/readerChoices.json similarity index 100% rename from codex_vue/src/choices/readerChoices.json rename to codex/choices/readerChoices.json diff --git a/codex_api/choices/static.py b/codex/choices/static.py similarity index 94% rename from codex_api/choices/static.py rename to codex/choices/static.py index 94be96f77..51421eba6 100644 --- a/codex_api/choices/static.py +++ b/codex/choices/static.py @@ -1,8 +1,10 @@ """Static choices that aren't derived from models.""" +from pathlib import Path + import simplejson as json -VUEX_MODULES = "codex_vue/src/choices" +VUEX_MODULES = Path(__file__).parent CHOICES_FNS = ( f"{VUEX_MODULES}/browserChoices.json", f"{VUEX_MODULES}/readerChoices.json", diff --git a/codex/hypercorn.toml.default b/codex/hypercorn.toml.default new file mode 100644 index 000000000..20aa3532a --- /dev/null +++ b/codex/hypercorn.toml.default @@ -0,0 +1,3 @@ +bind = ["0.0.0.0:9810"] +quick_bind = ["0.0.0.0:9810"] +root_path = "" diff --git a/codex_api/choices/__init__.py b/codex/librarian/__init__.py similarity index 100% rename from codex_api/choices/__init__.py rename to codex/librarian/__init__.py diff --git a/codex/librarian/cover.py b/codex/librarian/cover.py new file mode 100644 index 000000000..63674c11c --- /dev/null +++ b/codex/librarian/cover.py @@ -0,0 +1,73 @@ +import logging + +from io import BytesIO +from pathlib import Path + +from comicbox.comic_archive import ComicArchive +from PIL import Image + +from codex.librarian.queue import QUEUE +from codex.librarian.queue import LibraryChangedTask +from codex.models import Comic +from codex.settings import CONFIG_STATIC + + +THUMBNAIL_SIZE = (120, 180) + + +COVER_ROOT = Path(f"{CONFIG_STATIC}/covers") +LOG = logging.getLogger(__name__) + + +def cleanup_cover_dirs(path): + """Recursively remove empty cover directories""" + if COVER_ROOT not in path.parents: + return + try: + path.rmdir() + cleanup_cover_dirs(path.parent) + except OSError: + pass + + +def purge_cover(comic): + """Remove one cover thumb from the filesystem.""" + cover_path = COVER_ROOT / comic.cover_path + try: + # XXX python 3.8 missing_ok=True + # Switch to python 3.8 requirement begginning of 2021 + cover_path.unlink() + except FileNotFoundError: + pass + cleanup_cover_dirs(cover_path.parent) + + +def purge_all_covers(library): + """Remove all cover thumbs for a library.""" + comics = Comic.objects.only("path", "library").filter(library=library) + for comic in comics: + purge_cover(comic) + + +def create_comic_cover(comic_path, db_cover_path, force=False): + """Create a comic cover thumnail and save it to disk.""" + try: + fs_cover_path = COVER_ROOT / db_cover_path + if fs_cover_path.exists() and not force: + LOG.debug(f"Cover already exists {comic_path} {db_cover_path}") + return + fs_cover_path.parent.mkdir(exist_ok=True, parents=True) + + if comic_path is None: + comic_path = Comic.objects.only("path").get(cover_path=db_cover_path).path + + # Reopens the car, so slightly inefficient. + car = ComicArchive(comic_path) + im = Image.open(BytesIO(car.get_cover_image())) + im.thumbnail(THUMBNAIL_SIZE) + im.save(fs_cover_path, im.format) + LOG.info(f"Created cover thumbnail for: {comic_path}") + QUEUE.put(LibraryChangedTask()) + except Exception as exc: + LOG.exception(exc) + LOG.error(f"Failed to create cover thumb for {comic_path}") diff --git a/codex_api/librarian/crond.py b/codex/librarian/crond.py similarity index 75% rename from codex_api/librarian/crond.py rename to codex/librarian/crond.py index e0cabb5b3..e161cfc9e 100644 --- a/codex_api/librarian/crond.py +++ b/codex/librarian/crond.py @@ -4,9 +4,9 @@ from threading import Condition from threading import Thread -from codex_api.librarian.queue import QUEUE -from codex_api.librarian.queue import ScannerCronTask -from codex_api.librarian.queue import WatcherCronTask +from codex.librarian.queue import QUEUE +from codex.librarian.queue import ScannerCronTask +from codex.librarian.queue import WatcherCronTask LOG = logging.getLogger(__name__) @@ -24,10 +24,8 @@ def worker(self, cond): LOG.info("Started scan cron") with cond: while self.run_thread: - task = ScannerCronTask() - QUEUE.put(task) - task = WatcherCronTask() - QUEUE.put(task) + QUEUE.put(ScannerCronTask(sleep=0)) + QUEUE.put(WatcherCronTask(sleep=0)) cond.wait(timeout=self.WAIT_INTERVAL) LOG.info("Stopped scan cron.") diff --git a/codex_api/librarian/daemon.py b/codex/librarian/daemon.py similarity index 57% rename from codex_api/librarian/daemon.py rename to codex/librarian/daemon.py index 574bc35ea..d13f70664 100644 --- a/codex_api/librarian/daemon.py +++ b/codex/librarian/daemon.py @@ -3,8 +3,8 @@ def start_daemons(): """Start the daemons. But don't import them until django is set up.""" - from codex_api.librarian.librariand import start_librarian - from codex_api.websocket import start_flood_control_worker + from codex.librarian.librariand import start_librarian + from codex.websocket_server import start_flood_control_worker start_librarian() start_flood_control_worker() @@ -12,8 +12,8 @@ def start_daemons(): def stop_daemons(): """Stop the daemons. But don't import them until django is set up.""" - from codex_api.librarian.librariand import stop_librarian - from codex_api.websocket import stop_flood_control_worker + from codex.librarian.librariand import stop_librarian + from codex.websocket_server import stop_flood_control_worker stop_librarian() stop_flood_control_worker() diff --git a/codex_api/librarian/importer.py b/codex/librarian/importer.py similarity index 84% rename from codex_api/librarian/importer.py rename to codex/librarian/importer.py index 3b13cb6ea..fb5f16369 100644 --- a/codex_api/librarian/importer.py +++ b/codex/librarian/importer.py @@ -6,38 +6,33 @@ import logging import os -from io import BytesIO from pathlib import Path import pycountry import regex +from comicbox.comic_archive import ComicArchive from django.db.models import ForeignKey from django.db.models import ManyToManyField from fnvhash import fnv1a_32 -from PIL import Image - -from codex.settings import STATIC_ROOT -from codex_api.librarian.queue import QUEUE -from codex_api.librarian.queue import LibraryChangedTask -from codex_api.models import Comic -from codex_api.models import Credit -from codex_api.models import Folder -from codex_api.models import Imprint -from codex_api.models import Library -from codex_api.models import Publisher -from codex_api.models import Series -from codex_api.models import Volume -from comicbox.comic_archive import ComicArchive +from codex.librarian.cover import purge_cover +from codex.librarian.queue import QUEUE +from codex.librarian.queue import ComicCoverCreateTask +from codex.librarian.queue import LibraryChangedTask +from codex.models import Comic +from codex.models import Credit +from codex.models import Folder +from codex.models import Imprint +from codex.models import Library +from codex.models import Publisher +from codex.models import Series +from codex.models import Volume -# actual filesystem route. -FS_STATIC_PREFIX = Path("config") / STATIC_ROOT +# actual filesystem route. COMIC_MATCHER = regex.compile(r"\.cb[rz]$") - LOG = logging.getLogger(__name__) -LOG.setLevel(logging.DEBUG) def obj_deleted(src_path, cls): @@ -48,12 +43,7 @@ def obj_deleted(src_path, cls): LOG.debug(f"{cls.__name__} {src_path} does not exist. Can't delete.") return if cls == Comic: - cover_path = FS_STATIC_PREFIX / obj.cover_path - try: - # TODO python 3.8 missing_ok=True - cover_path.unlink() - except FileNotFoundError: - pass + purge_cover(obj) obj.delete() LOG.info(f"Deleted {cls.__name__} {src_path}") QUEUE.put(LibraryChangedTask()) @@ -77,7 +67,9 @@ def obj_moved(src_path, dest_path, cls): LOG.debug(f"Ignoring {dest_path} folder without comics.") return - obj = cls.objects.get(path=src_path) + obj = cls.objects.only("path", "library", "parent_folder", "folder").get( + path=src_path + ) if cls.objects.filter(path=dest_path).exists(): """ Files get moved before folders which means they create new folders @@ -109,13 +101,11 @@ class Importer: BROWSE_TREE_COUNT_FIELDS = {Series: "volume_count", Volume: "issue_count"} SPECIAL_FKS = ("myself", "volume", "series", "imprint", "publisher", "library") EXCLUDED_MODEL_KEYS = ("id", "parent_folder") - FIELD_PREFIX_LEN = len("codex_api.Comic.") + FIELD_PREFIX_LEN = len("codex.Comic.") # Covers HEX_FILL = 8 PATH_STEP = 2 - COVER_ROOT = Path("covers") - THUMBNAIL_SIZE = (180, 180) def __init__(self, library_id, path): """Set the state for this import.""" @@ -136,19 +126,10 @@ def hex_path(self): def get_cover_path(self): """Get path to a cover image, creating the image if not found.""" - cover_path = self.COVER_ROOT / self.hex_path() - try: - im = Image.open(BytesIO(self.car.get_cover_image())) - im.thumbnail(self.THUMBNAIL_SIZE) - db_cover_path = cover_path.with_suffix("." + im.format.lower()) - fs_cover_path = FS_STATIC_PREFIX / db_cover_path - fs_cover_path.parent.mkdir(exist_ok=True, parents=True) - im.save(fs_cover_path, im.format) - LOG.debug(f"Cached cover for: {self.path}") - except Exception as exc: - LOG.exception(exc) - LOG.error(f"Failed to create cover thumb for {self.path}") - return None + hex_path = self.hex_path() + db_cover_path = hex_path.with_suffix(".jpg") + task = ComicCoverCreateTask(self.path, db_cover_path) + QUEUE.put(task) return db_cover_path @staticmethod @@ -160,9 +141,7 @@ def get_or_create_simple_model(name, cls): # find deleted models and undelete them too defaults = {} defaults["name"] = name - inst, created = cls.objects.get_or_create( - defaults=defaults, name__iexact=name - ) + inst, created = cls.objects.get_or_create(defaults=defaults, name__iexact=name) if created: LOG.info(f"Created {cls.__name__} {inst.name}") return inst @@ -181,7 +160,7 @@ def get_foreign_keys(self): return foreign_keys def get_many_to_many_instances(self): - """Create or update all the ManyToMany fields.""" + """Get or Create all the ManyToMany fields.""" m2m_fields = {} # for key, cls, in M2M_KEYS.items(): for field in Comic._meta.get_fields(): @@ -202,7 +181,7 @@ def get_many_to_many_instances(self): return m2m_fields def get_credits(self): - """Create or update credits, a complicated ManyToMany Field.""" + """Get or Create credits, a complicated ManyToMany Field.""" credits_md = self.md.get("credits") if not credits_md: return @@ -221,9 +200,7 @@ def get_credits(self): search[field.name] = inst defaults = {} defaults.update(search) - credit, created = Credit.objects.get_or_create( - defaults=defaults, **search - ) + credit, created = Credit.objects.get_or_create(defaults=defaults, **search) credits.append(credit) if created: LOG.info(f"Created credit {credit.role.name}: {credit.person.name}") @@ -231,7 +208,7 @@ def get_credits(self): return credits def get_or_create_browse_tree(self, cls, tree): - """Update or create a single level of the comic's publish tree.""" + """Get or create a single level of the comic's publish tree.""" md_key = cls.__name__.lower() # current level name = self.md.get(md_key) # name of the current level defaults = {} @@ -335,7 +312,7 @@ def import_metadata(self): self.md["series"], self.md["volume"], ) = self.get_browse_containers() - library = Library.objects.get(pk=self.library_id) + library = Library.objects.only("pk", "path").get(pk=self.library_id) self.set_locales() credits = self.get_credits() m2m_fields = self.get_many_to_many_instances() diff --git a/codex_api/librarian/librariand.py b/codex/librarian/librariand.py similarity index 53% rename from codex_api/librarian/librariand.py rename to codex/librarian/librariand.py index 3b70393c4..a289fb131 100644 --- a/codex_api/librarian/librariand.py +++ b/codex/librarian/librariand.py @@ -2,45 +2,66 @@ import logging import time +from multiprocessing import Pool from multiprocessing import Process +from multiprocessing import set_start_method +from time import sleep import simplejson as json -import websocket - -from codex_api.librarian.crond import Crond -from codex_api.librarian.importer import import_comic -from codex_api.librarian.importer import obj_deleted -from codex_api.librarian.importer import obj_moved -from codex_api.librarian.queue import QUEUE -from codex_api.librarian.queue import ComicDeletedTask -from codex_api.librarian.queue import ComicModifiedTask -from codex_api.librarian.queue import ComicMovedTask -from codex_api.librarian.queue import FolderDeletedTask -from codex_api.librarian.queue import FolderMovedTask -from codex_api.librarian.queue import LibraryChangedTask -from codex_api.librarian.queue import ScannerCronTask -from codex_api.librarian.queue import ScanRootTask -from codex_api.librarian.queue import WatcherCronTask -from codex_api.librarian.queue import WatchLibraryTask -from codex_api.librarian.scanner import scan_cron -from codex_api.librarian.scanner import scan_root -from codex_api.librarian.watcherd import Uatu -from codex_api.models import Comic -from codex_api.models import Folder -from codex_api.websocket import BROADCAST_MSG -from codex_api.websocket import BROADCAST_SECRET -from codex_api.websocket import UNSUBSCRIBE_MSG + +from django.apps import apps +from websocket import create_connection + + +if not apps.ready: + import django + + django.setup() + +from multiprocessing import Value + +from codex.librarian.cover import create_comic_cover +from codex.librarian.crond import Crond +from codex.librarian.importer import import_comic +from codex.librarian.importer import obj_deleted +from codex.librarian.importer import obj_moved +from codex.librarian.queue import QUEUE +from codex.librarian.queue import ComicCoverCreateTask +from codex.librarian.queue import ComicDeletedTask +from codex.librarian.queue import ComicModifiedTask +from codex.librarian.queue import ComicMovedTask +from codex.librarian.queue import FolderDeletedTask +from codex.librarian.queue import FolderMovedTask +from codex.librarian.queue import LibraryChangedTask +from codex.librarian.queue import ScannerCronTask +from codex.librarian.queue import ScanRootTask +from codex.librarian.queue import WatcherCronTask +from codex.librarian.scanner import scan_cron +from codex.librarian.scanner import scan_root +from codex.librarian.watcherd import Uatu +from codex.models import Comic +from codex.models import Folder +from codex.websocket_server import BROADCAST_MSG +from codex.websocket_server import BROADCAST_SECRET +from codex.websocket_server import LIBRARY_CHANGED_MSG +from codex.websocket_server import UNSUBSCRIBE_MSG # from django.utils.autoreload import file_changed LOG = logging.getLogger(__name__) -PORT = 8000 +PORT = Value("i", 9810) # Shared memory overwritten in run.py BROADCAST_PATH = "broadcast" -BROADCAST_URL = f"ws://localhost:{PORT}/{BROADCAST_PATH}" +BROADCAST_URL_TMPL = "ws://localhost:{port}/" + BROADCAST_PATH SHUTDOWN_MSG = "shutdown" MAX_WS_ATTEMPTS = 4 +librarian_proc = None +# XXX Fixes QUEUE sharing with default spawn start method. The spawn +# method is also very very slow. Use fork and the +# OBJC_DISABLE_INITIALIZE_FORK_SAFETY environment variable for macOS. +# https://bugs.python.org/issue40106 +set_start_method("fork", force=True) def get_websocket(): @@ -50,7 +71,8 @@ def get_websocket(): while ws is None or not ws.connected and attempts <= MAX_WS_ATTEMPTS: time.sleep(0.5) try: - ws = websocket.create_connection(BROADCAST_URL) + broadcast_url = BROADCAST_URL_TMPL.format(port=PORT.value) + ws = create_connection(broadcast_url) except ConnectionRefusedError: attempts += 1 if ws and ws.connected: @@ -89,6 +111,8 @@ def librarian(): crond = Crond() watcher.start() crond.start() + pool = Pool() + while run: task = QUEUE.get() try: @@ -96,10 +120,11 @@ def librarian(): scan_root(task.library_id, task.force) elif isinstance(task, ComicModifiedTask): import_comic(task.library_id, task.src_path) - # TODO use a higher performance db? - # import is cpu bound, so farm it out. - # pool.apply_async(import_comic, - # args=(task.library_id, task.src_path)) + elif isinstance(task, ComicCoverCreateTask): + # Cover creation is cpu bound, farm it out. + pool.apply_async( + create_comic_cover, args=(task.src_path, task.db_cover_path), + ) elif isinstance(task, FolderMovedTask): obj_moved(task.src_path, task.dest_path, Folder) elif isinstance(task, ComicMovedTask): @@ -109,12 +134,12 @@ def librarian(): elif isinstance(task, FolderDeletedTask): obj_deleted(task.src_path, Folder) elif isinstance(task, LibraryChangedTask): - ws = send_json(ws, BROADCAST_MSG, "libraryChanged") - elif isinstance(task, WatchLibraryTask): - watcher.set_library_watch(task.library_pk, task.watch) + ws = send_json(ws, BROADCAST_MSG, LIBRARY_CHANGED_MSG) elif isinstance(task, WatcherCronTask): + sleep(task.sleep) watcher.set_all_library_watches() elif isinstance(task, ScannerCronTask): + sleep(task.sleep) scan_cron() elif task == SHUTDOWN_MSG: run = False @@ -124,23 +149,27 @@ def librarian(): LOG.warning(exc) except Exception as exc: LOG.exception(exc) + pool.close() crond.stop() watcher.stop() crond.join() watcher.join() + pool.join() LOG.info("Stopped Librarian.") def start_librarian(): """Start the worker process.""" - global proc - proc = Process(target=librarian, name="codex-librarian", daemon=True) - proc.start() + global librarian_proc + librarian_proc = Process(target=librarian, name="codex-librarian", daemon=False) + librarian_proc.start() # this signal is thrown by runserver which i don't use anymore # file_changed.connect(stop_librarian) def stop_librarian(*args, **kwargs): """Stop the librarian process.""" + global librarian_proc QUEUE.put(SHUTDOWN_MSG) - proc.join() + if librarian_proc: + librarian_proc.join() diff --git a/codex_api/librarian/queue.py b/codex/librarian/queue.py similarity index 78% rename from codex_api/librarian/queue.py rename to codex/librarian/queue.py index 8eab0150c..e36ee95d9 100644 --- a/codex_api/librarian/queue.py +++ b/codex/librarian/queue.py @@ -23,7 +23,13 @@ class ComicModifiedTask(ComicTask): """Created and Modified comics share the same task.""" library_id: int - pass + + +@dataclass +class ComicCoverCreateTask(ComicTask): + """Create a comic cover.""" + + db_cover_path: str @dataclass @@ -55,29 +61,28 @@ class FolderDeletedTask(ComicTask): @dataclass -class LibraryChangedTask: - """Library Changed.""" +class SleepTask: + """A task that must sleep a tiny bit for db consistency.""" - pass + sleep: int @dataclass -class WatchLibraryTask: - """Task for watcherd.""" +class LibraryChangedTask: + """Library Changed.""" - library_pk: int - watch: bool + pass @dataclass -class WatcherCronTask: +class WatcherCronTask(SleepTask): """Cron for watcherd.""" pass @dataclass -class ScannerCronTask: +class ScannerCronTask(SleepTask): """Cron for scanner.""" pass diff --git a/codex_api/librarian/scanner.py b/codex/librarian/scanner.py similarity index 84% rename from codex_api/librarian/scanner.py rename to codex/librarian/scanner.py index ef1d157ff..a66dee367 100644 --- a/codex_api/librarian/scanner.py +++ b/codex/librarian/scanner.py @@ -7,16 +7,16 @@ from django.utils import timezone -from codex_api.librarian.importer import COMIC_MATCHER -from codex_api.librarian.queue import QUEUE -from codex_api.librarian.queue import ComicDeletedTask -from codex_api.librarian.queue import ComicModifiedTask -from codex_api.librarian.queue import FolderDeletedTask -from codex_api.librarian.queue import ScanRootTask -from codex_api.models import SCHEMA_VERSION -from codex_api.models import Comic -from codex_api.models import Folder -from codex_api.models import Library +from codex.librarian.importer import COMIC_MATCHER +from codex.librarian.queue import QUEUE +from codex.librarian.queue import ComicDeletedTask +from codex.librarian.queue import ComicModifiedTask +from codex.librarian.queue import FolderDeletedTask +from codex.librarian.queue import ScanRootTask +from codex.models import SCHEMA_VERSION +from codex.models import Comic +from codex.models import Folder +from codex.models import Library LOG = logging.getLogger(__name__) @@ -29,7 +29,7 @@ def scan_for_new(library): num_new = 0 num_skipped = 0 num_passed = 0 - for root, dirnames, filenames in os.walk(library.path): + for root, _, filenames in os.walk(library.path): walk_root = Path(root) LOG.debug(f"Scanning {walk_root}") for filename in sorted(filenames): @@ -66,7 +66,7 @@ def scan_existing(library, cls, force=False): num_removed = 0 num_updated = 0 num_passed = 0 - objs = cls.objects.filter(library=library) + objs = cls.objects.filter(library=library).only("path") for obj in objs: path = Path(obj.path) task = None @@ -95,7 +95,7 @@ def scan_existing(library, cls, force=False): def scan_root(pk, force=False): """Scan a library.""" - library = Library.objects.get(pk=pk) + library = Library.objects.only("scan_in_progress", "last_scan", "path").get(pk=pk) if library.scan_in_progress: LOG.info(f"Scan in progress for {library.path}. Not rescanning") return @@ -124,7 +124,7 @@ def scan_root(pk, force=False): def scan_all_roots(force): """Scan all the librarys.""" LOG.info("Scanning all librarys...") - rps = Library.objects.all() + rps = Library.objects.all().only("pk") for library in rps: task = ScanRootTask(library.pk, force) QUEUE.put(task) @@ -144,7 +144,9 @@ def is_time_to_scan(library): def scan_cron(): """Regular cron for scanning.""" - librarys = Library.objects.filter(enable_scan_cron=True) + librarys = Library.objects.filter(enable_scan_cron=True).only( + "pk", "schema_version", "last_scan" + ) for library in librarys: force_import = library.schema_version < SCHEMA_VERSION if is_time_to_scan(library) or force_import: diff --git a/codex_api/librarian/watcherd.py b/codex/librarian/watcherd.py similarity index 87% rename from codex_api/librarian/watcherd.py rename to codex/librarian/watcherd.py index 84baf111e..e1a657c1b 100644 --- a/codex_api/librarian/watcherd.py +++ b/codex/librarian/watcherd.py @@ -8,14 +8,14 @@ from watchdog.events import FileSystemEventHandler from watchdog.observers import Observer -from codex_api.librarian.importer import COMIC_MATCHER -from codex_api.librarian.queue import QUEUE -from codex_api.librarian.queue import ComicDeletedTask -from codex_api.librarian.queue import ComicModifiedTask -from codex_api.librarian.queue import ComicMovedTask -from codex_api.librarian.queue import FolderDeletedTask -from codex_api.librarian.queue import FolderMovedTask -from codex_api.models import Library +from codex.librarian.importer import COMIC_MATCHER +from codex.librarian.queue import QUEUE +from codex.librarian.queue import ComicDeletedTask +from codex.librarian.queue import ComicModifiedTask +from codex.librarian.queue import ComicMovedTask +from codex.librarian.queue import FolderDeletedTask +from codex.librarian.queue import FolderMovedTask +from codex.models import Library LOG = logging.getLogger(__name__) @@ -42,7 +42,7 @@ def get_size(path, is_dir): path = Path(path) if is_dir: size = 0 - for root, dns, fns in os.walk(path): + for root, _, fns in os.walk(path): rp = Path(root) for fn in fns: full_path = Path(rp / fn) @@ -170,6 +170,15 @@ def set_library_watch(self, pk, watch): def set_all_library_watches(self): """Watch or unwatch all librareis according to the db.""" - rps = Library.objects.all().values("pk", "enable_watch") + rps = ( + Library.objects.all() + .only("pk", "enable_watch") + .values("pk", "enable_watch") + ) + active_watch_pks = set() for rp in rps: self.set_library_watch(rp.get("pk"), rp.get("enable_watch")) + active_watch_pks.add(rp.get("pk")) + missing_watch_pks = set(self._pk_watches.keys()) - active_watch_pks + for pk in missing_watch_pks: + self.unwatch_library(pk) diff --git a/codex_api/lifespan.py b/codex/lifespan.py similarity index 90% rename from codex_api/lifespan.py rename to codex/lifespan.py index 898bb7822..ca9232aca 100644 --- a/codex_api/lifespan.py +++ b/codex/lifespan.py @@ -7,8 +7,8 @@ from asgiref.sync import sync_to_async -from codex_api.librarian.daemon import start_daemons -from codex_api.librarian.daemon import stop_daemons +from codex.librarian.daemon import start_daemons +from codex.librarian.daemon import stop_daemons LOG = logging.getLogger(__name__) diff --git a/codex_api/middleware.py b/codex/middleware.py similarity index 100% rename from codex_api/middleware.py rename to codex/middleware.py diff --git a/codex/migrations/0001_init.py b/codex/migrations/0001_init.py new file mode 100644 index 000000000..2b2b43a4a --- /dev/null +++ b/codex/migrations/0001_init.py @@ -0,0 +1,624 @@ +# Generated by Django 3.1 on 2020-08-21 18:59 + +import datetime + +import django.db.models.deletion + +from django.conf import settings +from django.db import migrations +from django.db import models + +import codex.models + + +def init_admin_flags(apps, schema_editor): + """Initalize the admin flag rows""" + # AdminFlag = apps.get_model("codex", "AdminFlag") # noqa N806 + for name in codex.models.AdminFlag.FLAG_NAMES: + codex.models.AdminFlag.objects.update_or_create(name=name) + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ("sessions", "0001_initial"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name="Character", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("name", models.CharField(db_index=True, max_length=32)), + ], + options={"abstract": False, "unique_together": {("name",)},}, + ), + migrations.CreateModel( + name="Imprint", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("is_default", models.BooleanField(default=False)), + ("sort_name", models.CharField(max_length=32)), + ("name", models.CharField(default="Main Imprint", max_length=32)), + ], + ), + migrations.CreateModel( + name="Library", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ( + "path", + models.CharField( + db_index=True, + max_length=128, + unique=True, + validators=[codex.models.validate_dir_exists], + ), + ), + ("enable_watch", models.BooleanField(db_index=True, default=True)), + ("enable_scan_cron", models.BooleanField(db_index=True, default=True)), + ( + "scan_frequency", + models.DurationField(default=datetime.timedelta(seconds=43200)), + ), + ("last_scan", models.DateTimeField(null=True)), + ("scan_in_progress", models.BooleanField(default=False)), + ("schema_version", models.PositiveSmallIntegerField(default=0)), + ], + options={"abstract": False,}, + ), + migrations.CreateModel( + name="Publisher", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("is_default", models.BooleanField(default=False)), + ("sort_name", models.CharField(db_index=True, max_length=32)), + ("name", models.CharField(default="No Publisher", max_length=32)), + ], + options={"unique_together": {("name", "is_default")},}, + ), + migrations.CreateModel( + name="Series", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("is_default", models.BooleanField(default=False)), + ("sort_name", models.CharField(db_index=True, max_length=32)), + ("name", models.CharField(default="Default Series", max_length=32)), + ("volume_count", models.PositiveSmallIntegerField(null=True)), + ( + "imprint", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="codex.imprint" + ), + ), + ( + "publisher", + models.ForeignKey( + on_delete=codex.models.Publisher.get_default_publisher, + to="codex.publisher", + ), + ), + ], + options={"unique_together": {("name", "imprint", "is_default")},}, + ), + migrations.CreateModel( + name="Volume", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("is_default", models.BooleanField(default=False)), + ("sort_name", models.CharField(db_index=True, max_length=32)), + ("name", models.CharField(default="", max_length=32)), + ( + "issue_count", + models.DecimalField(decimal_places=2, max_digits=6, null=True), + ), + ( + "imprint", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="codex.imprint" + ), + ), + ( + "publisher", + models.ForeignKey( + on_delete=codex.models.Publisher.get_default_publisher, + to="codex.publisher", + ), + ), + ( + "series", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="codex.series" + ), + ), + ], + options={"unique_together": {("name", "series", "is_default")},}, + ), + migrations.CreateModel( + name="Team", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("name", models.CharField(db_index=True, max_length=32)), + ], + options={"abstract": False, "unique_together": {("name",)},}, + ), + migrations.CreateModel( + name="Tag", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("name", models.CharField(db_index=True, max_length=32)), + ], + options={"abstract": False, "unique_together": {("name",)},}, + ), + migrations.CreateModel( + name="StoryArc", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("name", models.CharField(db_index=True, max_length=32)), + ], + options={"abstract": False, "unique_together": {("name",)},}, + ), + migrations.CreateModel( + name="SeriesGroup", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("name", models.CharField(db_index=True, max_length=32)), + ], + options={"abstract": False, "unique_together": {("name",)},}, + ), + migrations.CreateModel( + name="Location", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("name", models.CharField(db_index=True, max_length=32)), + ], + options={"abstract": False, "unique_together": {("name",)},}, + ), + migrations.AddField( + model_name="imprint", + name="publisher", + field=models.ForeignKey( + on_delete=models.SET(codex.models.Publisher.get_default_publisher), + to="codex.publisher", + ), + ), + migrations.CreateModel( + name="Genre", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("name", models.CharField(db_index=True, max_length=32)), + ], + options={"abstract": False, "unique_together": {("name",)},}, + ), + migrations.CreateModel( + name="Folder", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("name", models.CharField(db_index=True, max_length=32)), + ( + "path", + models.CharField( + db_index=True, + max_length=128, + validators=[codex.models.validate_dir_exists], + ), + ), + ("sort_name", models.CharField(max_length=32)), + ( + "library", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="codex.library" + ), + ), + ( + "parent_folder", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="codex.folder", + ), + ), + ], + options={"unique_together": {("library", "path")},}, + ), + migrations.CreateModel( + name="CreditRole", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("name", models.CharField(db_index=True, max_length=32)), + ], + options={"abstract": False, "unique_together": {("name",)},}, + ), + migrations.CreateModel( + name="CreditPerson", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("name", models.CharField(db_index=True, max_length=32)), + ], + options={"abstract": False, "unique_together": {("name",)},}, + ), + migrations.CreateModel( + name="Credit", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ( + "person", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="codex.creditperson", + ), + ), + ( + "role", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="codex.creditrole", + ), + ), + ], + options={"unique_together": {("person", "role")},}, + ), + migrations.CreateModel( + name="Comic", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("path", models.CharField(db_index=True, max_length=128)), + ( + "issue", + models.DecimalField( + db_index=True, decimal_places=2, default=0.0, max_digits=6 + ), + ), + ("title", models.CharField(db_index=True, max_length=64, null=True)), + ("year", models.PositiveSmallIntegerField(null=True)), + ("month", models.PositiveSmallIntegerField(null=True)), + ("day", models.PositiveSmallIntegerField(null=True)), + ("summary", models.TextField(null=True)), + ("notes", models.TextField(null=True)), + ("description", models.TextField(null=True)), + ( + "critical_rating", + models.CharField(db_index=True, max_length=32, null=True), + ), + ( + "maturity_rating", + models.CharField(db_index=True, max_length=32, null=True), + ), + ( + "user_rating", + models.CharField(db_index=True, max_length=32, null=True), + ), + ("country", models.CharField(db_index=True, max_length=32, null=True)), + ("language", models.CharField(db_index=True, max_length=16, null=True)), + ( + "page_count", + models.PositiveSmallIntegerField(db_index=True, default=0), + ), + ("cover_image", models.CharField(max_length=64, null=True)), + ("read_ltr", models.BooleanField(default=True)), + ("web", models.URLField(null=True)), + ("format", models.CharField(max_length=16, null=True)), + ("scan_info", models.CharField(max_length=32, null=True)), + ("sort_name", models.CharField(db_index=True, max_length=32)), + ("date", models.DateField(db_index=True, null=True)), + ("decade", models.PositiveSmallIntegerField(db_index=True, null=True)), + ("size", models.PositiveSmallIntegerField(db_index=True)), + ("max_page", models.PositiveSmallIntegerField(default=0)), + ("cover_path", models.CharField(max_length=32)), + ("characters", models.ManyToManyField(to="codex.Character")), + ("credits", models.ManyToManyField(to="codex.Credit")), + ("folder", models.ManyToManyField(to="codex.Folder")), + ("genres", models.ManyToManyField(to="codex.Genre")), + ( + "imprint", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="codex.imprint" + ), + ), + ( + "library", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="codex.library" + ), + ), + ("locations", models.ManyToManyField(to="codex.Location")), + ( + "myself", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="comic", + to="codex.comic", + ), + ), + ( + "parent_folder", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="comic_in", + to="codex.folder", + ), + ), + ( + "publisher", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="codex.publisher", + ), + ), + ( + "series", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="codex.series" + ), + ), + ("series_groups", models.ManyToManyField(to="codex.SeriesGroup")), + ("story_arcs", models.ManyToManyField(to="codex.StoryArc")), + ("tags", models.ManyToManyField(to="codex.Tag")), + ("teams", models.ManyToManyField(to="codex.Team")), + ( + "volume", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="codex.volume" + ), + ), + ], + options={"unique_together": {("path", "volume", "year", "issue")},}, + ), + migrations.AlterUniqueTogether( + name="imprint", unique_together={("name", "publisher", "is_default")}, + ), + migrations.CreateModel( + name="AdminFlag", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("name", models.CharField(db_index=True, max_length=32)), + ("on", models.BooleanField(default=True)), + ], + options={"abstract": False, "unique_together": {("name",)},}, + ), + migrations.AlterField( + model_name="imprint", + name="sort_name", + field=models.CharField(db_index=True, max_length=32), + ), + migrations.CreateModel( + name="UserBookmark", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ( + "bookmark", + models.PositiveSmallIntegerField(db_index=True, null=True), + ), + ("finished", models.BooleanField(db_index=True, default=False)), + ( + "fit_to", + models.CharField( + default=None, + max_length=6, + null=True, + validators=[codex.models.validate_fit_to_choice], + ), + ), + ("two_pages", models.BooleanField(default=None, null=True)), + ( + "comic", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="codex.comic" + ), + ), + ( + "session", + models.ForeignKey( + null=True, + on_delete=codex.models.cascade_if_user_null, + to="sessions.session", + ), + ), + ( + "user", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={"unique_together": {("user", "session", "comic")},}, + ), + migrations.RunPython(code=init_admin_flags,), + ] diff --git a/codex_api/librarian/__init__.py b/codex/migrations/__init__.py similarity index 100% rename from codex_api/librarian/__init__.py rename to codex/migrations/__init__.py diff --git a/codex_api/models.py b/codex/models.py similarity index 82% rename from codex_api/models.py rename to codex/models.py index b28052c56..69fcf4d50 100644 --- a/codex_api/models.py +++ b/codex/models.py @@ -23,14 +23,13 @@ from django.db.models import URLField from django.utils.translation import gettext_lazy as _ -from codex_api.choices.static import CHOICES +from codex.choices.static import CHOICES LOG = getLogger(__name__) DEFAULT_SCAN_FREQUENCY = datetime.timedelta(seconds=12 * 60 * 60) -DEFAULT_COVER_PATH = "codex/default_cover.png" SCHEMA_VERSION = 1 @@ -51,7 +50,7 @@ class BrowseContainerModel(BaseModel): """Models that need parents and default to an default parent.""" is_default = BooleanField(default=False) - sort_name = CharField(max_length=32) + sort_name = CharField(db_index=True, max_length=32) class Meta: """Without this a real table is created and joined to.""" @@ -202,9 +201,11 @@ def validate_dir_exists(path): class Library(BaseModel): """The library comic file live under.""" - path = CharField(unique=True, max_length=128, validators=[validate_dir_exists]) - enable_watch = BooleanField(default=True) - enable_scan_cron = BooleanField(default=True) + path = CharField( + unique=True, db_index=True, max_length=128, validators=[validate_dir_exists] + ) + enable_watch = BooleanField(db_index=True, default=True) + enable_scan_cron = BooleanField(db_index=True, default=True) scan_frequency = DurationField(default=DEFAULT_SCAN_FREQUENCY) last_scan = DateTimeField(null=True) scan_in_progress = BooleanField(default=False) @@ -218,7 +219,7 @@ def __str__(self): class NamedModel(BaseModel): """A for simple named tables.""" - name = CharField(max_length=32) + name = CharField(db_index=True, max_length=32) class Meta: """Defaults to uniquely named, must be overriden.""" @@ -236,7 +237,7 @@ class Folder(NamedModel): PARENT_FIELD = "folder" library = ForeignKey(Library, on_delete=CASCADE) - path = CharField(max_length=128, validators=[validate_dir_exists]) + path = CharField(max_length=128, db_index=True, validators=[validate_dir_exists]) parent_folder = ForeignKey("Folder", on_delete=CASCADE, null=True,) sort_name = CharField(max_length=32) @@ -333,13 +334,13 @@ class Comic(BaseModel): PLURAL = "Issues" - path = CharField(max_length=128) - volume = ForeignKey(Volume, on_delete=CASCADE) - series = ForeignKey(Series, on_delete=CASCADE) - imprint = ForeignKey(Imprint, on_delete=CASCADE) - publisher = ForeignKey(Publisher, on_delete=CASCADE) - issue = DecimalField(decimal_places=2, max_digits=6, default=0.0) - title = CharField(max_length=64, null=True) + path = CharField(db_index=True, max_length=128) + volume = ForeignKey(Volume, db_index=True, on_delete=CASCADE) + series = ForeignKey(Series, db_index=True, on_delete=CASCADE) + imprint = ForeignKey(Imprint, db_index=True, on_delete=CASCADE) + publisher = ForeignKey(Publisher, db_index=True, on_delete=CASCADE) + issue = DecimalField(db_index=True, decimal_places=2, max_digits=6, default=0.0) + title = CharField(db_index=True, max_length=64, null=True) # Date year = PositiveSmallIntegerField(null=True) month = PositiveSmallIntegerField(null=True) @@ -349,14 +350,14 @@ class Comic(BaseModel): notes = TextField(null=True) description = TextField(null=True) # Ratings - critical_rating = CharField(max_length=32, null=True) - maturity_rating = CharField(max_length=32, null=True) - user_rating = CharField(max_length=32, null=True) + critical_rating = CharField(db_index=True, max_length=32, null=True) + maturity_rating = CharField(db_index=True, max_length=32, null=True) + user_rating = CharField(db_index=True, max_length=32, null=True) # alpha2 fields for countries - country = CharField(max_length=32, null=True) - language = CharField(max_length=16, null=True) + country = CharField(db_index=True, max_length=32, null=True) + language = CharField(db_index=True, max_length=16, null=True) # misc - page_count = PositiveSmallIntegerField(default=0) + page_count = PositiveSmallIntegerField(db_index=True, default=0) cover_image = CharField(max_length=64, null=True) read_ltr = BooleanField(default=True) web = URLField(null=True) @@ -388,16 +389,16 @@ class Comic(BaseModel): # codex only library = ForeignKey(Library, on_delete=CASCADE) - sort_name = CharField(max_length=32) - date = DateField(null=True) - decade = PositiveSmallIntegerField(null=True) - size = PositiveSmallIntegerField() + sort_name = CharField(db_index=True, max_length=32) + date = DateField(db_index=True, null=True) + decade = PositiveSmallIntegerField(db_index=True, null=True) + size = PositiveSmallIntegerField(db_index=True) max_page = PositiveSmallIntegerField(default=0) parent_folder = ForeignKey( - Folder, on_delete=CASCADE, null=True, related_name="comic_in" + Folder, db_index=True, on_delete=CASCADE, null=True, related_name="comic_in" ) folder = ManyToManyField(Folder) - cover_path = CharField(max_length=32, default=DEFAULT_COVER_PATH) + cover_path = CharField(max_length=32) myself = ForeignKey("self", on_delete=CASCADE, null=True, related_name="comic") class Meta: @@ -431,12 +432,8 @@ def _get_display_issue(self): @property def header_name(self): """Set long name for disambiguation.""" - display_issue = self._get_display_issue() - header_name = ( - # f"{self.volume.series.display_name} " - # f"{self.volume.short_display_name} " - f"{display_issue}" - ) + header_name = self.volume.sort_name + " " + header_name += self._get_display_issue() issue_count = self.volume.issue_count if issue_count: header_name += f" of {issue_count}" @@ -451,12 +448,12 @@ def save(self, *args, **kwargs): """Save computed fields.""" self._set_date() self._set_decade() - self.sort_name = self.header_name + self.sort_name = f"{self.volume.sort_name} {self.issue:06.1f}" super().save(*args, **kwargs) class AdminFlag(NamedModel): - """A whole column just for one admin flag.""" + """Flags set by administrators.""" ENABLE_FOLDER_VIEW = "Enable Folder View" ENABLE_REGISTRATION = "Enable Registration" @@ -464,26 +461,6 @@ class AdminFlag(NamedModel): on = BooleanField(default=True) - @classmethod - def init_flag(cls, flag_name): - """Initialize a flag to its default value.""" - from django.db import connection - - table_names = connection.introspection.table_names() - if "codex_api_adminflag" not in table_names: - LOG.warn("Not intializing AdminFlags. They don't exist yet.") - return - - flag, created = cls.objects.get_or_create(name=flag_name) - if created: - LOG.debug(f"Initialized {flag.name} to {flag.on}") - - @classmethod - def init_all_flags(cls): - """Intialize all the flags.""" - for flag_name in cls.FLAG_NAMES: - cls.init_flag(flag_name) - def cascade_if_user_null(collector, field, sub_objs, using): """ @@ -523,11 +500,15 @@ def validate_fit_to_choice(choice): class UserBookmark(BaseModel): """Persist user's bookmarks and settings.""" - user = ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE, null=True) - session = ForeignKey(Session, on_delete=cascade_if_user_null, null=True) - comic = ForeignKey(Comic, on_delete=CASCADE) - bookmark = PositiveSmallIntegerField(null=True) - finished = BooleanField(default=False) + user = ForeignKey( + settings.AUTH_USER_MODEL, db_index=True, on_delete=CASCADE, null=True + ) + session = ForeignKey( + Session, db_index=True, on_delete=cascade_if_user_null, null=True + ) + comic = ForeignKey(Comic, db_index=True, on_delete=CASCADE) + bookmark = PositiveSmallIntegerField(db_index=True, null=True) + finished = BooleanField(default=False, db_index=True) fit_to = CharField( validators=[validate_fit_to_choice], null=True, default=None, max_length=6 ) diff --git a/codex/run.py b/codex/run.py new file mode 100755 index 000000000..1d6753b41 --- /dev/null +++ b/codex/run.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +import asyncio +import os +import shutil + +from logging import getLogger + +import django + +from django.contrib.auth import get_user_model +from django.core.management import call_command +from hypercorn.asyncio import serve +from hypercorn.config import Config + +from codex.asgi import application +from codex.librarian.librariand import PORT +from codex.settings import CODEX_PATH +from codex.settings import CONFIG_PATH +from codex.settings import CONFIG_STATIC + + +CONFIG_TOML = CONFIG_PATH / "hypercorn.toml" +CONFIG_DEFAULT_TOML = CODEX_PATH / "hypercorn.toml.default" + +LOG = getLogger(__name__) +DEV = bool(os.environ.get("DEV")) +RESET_ADMIN = bool(os.environ.get("CODEX_RESET_ADMIN")) + + +def ensure_config(): + """Ensure that a valid config exists.""" + # make the config dir and the static dir. + CONFIG_STATIC.mkdir(parents=True, exist_ok=True) + if not CONFIG_TOML.exists(): + shutil.copy(CONFIG_DEFAULT_TOML, CONFIG_TOML) + LOG.info(f"Copied default config to {CONFIG_TOML}") + + +def update_db(): + """Update the db to latest migrations.""" + call_command("makemigrations", "codex") + call_command("migrate") + + +def ensure_superuser(): + """Ensure there is a valid superuser.""" + User = get_user_model() # noqa N806 + + if RESET_ADMIN or not User.objects.filter(is_superuser=True).exists(): + admin_user, created = User.objects.update_or_create( + username="admin", defaults={"is_staff": True, "is_superuser": True}, + ) + admin_user.set_password("admin") + admin_user.save() + prefix = "Cre" if created else "Upd" + LOG.info(f"{prefix}ated admin user.") + + +def setup_db(): + """Setup the database before we run.""" + django.setup() + update_db() + ensure_superuser() + + +def run(): + config = Config.from_toml(CONFIG_TOML) + LOG.info(f"Loaded config from {CONFIG_TOML}") + if DEV: + config.use_reloader = True + LOG.info("Reload hypercorn if files change") + # Store port number in shared memory for librariand websocket + PORT.value = int(config.bind[0].split(":")[1]) + + # This papers over a macos crash that i think only happens on + # development server rapid restarts + os.environ["OBJC_DISABLE_INITIALIZE_FORK_SAFETY"] = "YES" + asyncio.run(serve(application, config)) + + +def main(): + if DEV: + LOG.setLevel("DEBUG") + ensure_config() + setup_db() + run() + + +if __name__ == "__main__": + main() diff --git a/codex_api/migrations/__init__.py b/codex/serializers/__init__.py similarity index 100% rename from codex_api/migrations/__init__.py rename to codex/serializers/__init__.py diff --git a/codex_api/serializers/auth.py b/codex/serializers/auth.py similarity index 79% rename from codex_api/serializers/auth.py rename to codex/serializers/auth.py index 545e0264f..c7c34226e 100644 --- a/codex_api/serializers/auth.py +++ b/codex/serializers/auth.py @@ -1,7 +1,6 @@ """Codex Auth Serializers.""" from django.contrib.auth.models import User -from django.urls import reverse_lazy from rest_framework.fields import BooleanField from rest_framework.fields import CharField from rest_framework.serializers import ModelSerializer @@ -11,13 +10,11 @@ class UserSerializer(ModelSerializer): """Serialize User model for UI.""" - adminURL = CharField(default=reverse_lazy("admin:index")) # noqa: N815 - class Meta: """Model spec.""" model = User - fields = ("pk", "username", "is_staff", "adminURL") + fields = ("pk", "username", "is_staff") read_only_fields = fields @@ -34,16 +31,19 @@ class Meta: """Model spec.""" model = User - fields = ("username", "password") + fields = ("username", "password", "timezone") extra_kwargs = {"password": {"write_only": True}} class UserLoginSerializer(UserCreateSerializer): """Serialize user login input.""" - # specificy this so it doesn't trigger the username unique constraint. + # specify this so it doesn't trigger the username unique constraint. username = CharField(min_length=2) + class Meta(UserCreateSerializer.Meta): + """Explicit meta inheritance required.""" + class RegistrationEnabledSerializer(Serializer): """Serialize one admin flag.""" diff --git a/codex_api/serializers/browse.py b/codex/serializers/browse.py similarity index 93% rename from codex_api/serializers/browse.py rename to codex/serializers/browse.py index 180dc2710..e103aef9f 100644 --- a/codex_api/serializers/browse.py +++ b/codex/serializers/browse.py @@ -10,8 +10,9 @@ from rest_framework.serializers import ListField from rest_framework.serializers import Serializer -from codex_api.choices.static import CHOICES -from codex_api.serializers.vuetify import VueIntChoiceSerializer +from codex.choices.static import CHOICES +from codex.serializers.vuetify import VueIntChoiceSerializer + VUE_MODEL_NULL_CODES = (-1, 0) @@ -59,8 +60,7 @@ class BrowserSettingsFilterSerializer(Serializer): validators=(validate_null_filter, validate_decades), ) characters = ListField( # noqa: N815 - child=IntegerField(allow_null=True), - validators=(validate_null_filter,), + child=IntegerField(allow_null=True), validators=(validate_null_filter,), ) @@ -73,9 +73,7 @@ class BrowserSettingsSerializer(Serializer): """ filters = BrowserSettingsFilterSerializer() - rootGroup = ChoiceField( # noqa: N815 - choices=tuple(CHOICES["rootGroup"].keys()) - ) + rootGroup = ChoiceField(choices=tuple(CHOICES["rootGroup"].keys())) # noqa: N815 sortBy = ChoiceField(choices=tuple(CHOICES["sort"].keys())) # noqa: N815 sortReverse = BooleanField() # noqa: N815 show = BrowserSettingsShowGroupFlagsSerializer() @@ -135,6 +133,7 @@ class BrowseListSerializer(Serializer): child=BrowseComicSerializer(read_only=True), allow_empty=True, read_only=True, ) formChoices = BrowserFormChoicesSerializer(read_only=True) # noqa: N815 + librariesExist = BooleanField(read_only=True) # noqa: N815 class BrowserOpenedSerializer(Serializer): @@ -142,4 +141,3 @@ class BrowserOpenedSerializer(Serializer): settings = BrowserSettingsSerializer(read_only=True) browseList = BrowseListSerializer(read_only=True) # noqa: N815 - librariesExist = BooleanField(read_only=True) # noqa: N815 diff --git a/codex_api/serializers/metadata.py b/codex/serializers/metadata.py similarity index 97% rename from codex_api/serializers/metadata.py rename to codex/serializers/metadata.py index 580d144d1..f3f7fbe9e 100644 --- a/codex_api/serializers/metadata.py +++ b/codex/serializers/metadata.py @@ -9,9 +9,9 @@ from rest_framework.serializers import Serializer from rest_framework.serializers import SerializerMethodField -from codex_api.models import Comic -from codex_api.models import Credit -from codex_api.models import UserBookmark +from codex.models import Comic +from codex.models import Credit +from codex.models import UserBookmark class NamedModelSerializer(Serializer): diff --git a/codex_api/serializers/read.py b/codex/serializers/read.py similarity index 74% rename from codex_api/serializers/read.py rename to codex/serializers/read.py index 08657526a..c65960978 100644 --- a/codex_api/serializers/read.py +++ b/codex/serializers/read.py @@ -5,7 +5,7 @@ from rest_framework.serializers import IntegerField from rest_framework.serializers import Serializer -from codex_api.choices.static import CHOICES +from codex.choices.static import CHOICES class ComicPageRouteSerializer(Serializer): @@ -28,7 +28,14 @@ class ComicReaderBothSettingsSerializer(Serializer): """For both the default and local comic settings.""" globl = ComicReaderSettingsSerializer(read_only=True) - local = ComicReaderSettingsSerializer(read_only=True, allow_null=True) + local = ComicReaderSettingsSerializer(read_only=True) + + +class ComicReaderRoutesSerializer(Serializer): + """Previous and next comic routes.""" + + prevBook = ComicPageRouteSerializer(allow_null=True, read_only=True) # noqa: N815 + nextBook = ComicPageRouteSerializer(allow_null=True, read_only=True) # noqa: N815 class ComicReaderInfoSerializer(Serializer): @@ -37,9 +44,4 @@ class ComicReaderInfoSerializer(Serializer): title = CharField(read_only=True) # noqa: N815 maxPage = IntegerField(read_only=True) # noqa: N815 settings = ComicReaderBothSettingsSerializer(read_only=True) - prevComicPage = ComicPageRouteSerializer( # noqa: N815 - allow_null=True, read_only=True - ) - nextComicPage = ComicPageRouteSerializer( # noqa: N815 - allow_null=True, read_only=True - ) + routes = ComicReaderRoutesSerializer(read_only=True) diff --git a/codex_api/serializers/vuetify.py b/codex/serializers/vuetify.py similarity index 100% rename from codex_api/serializers/vuetify.py rename to codex/serializers/vuetify.py diff --git a/codex/settings.py b/codex/settings.py index 9addd43eb..5dd7d9381 100644 --- a/codex/settings.py +++ b/codex/settings.py @@ -21,18 +21,28 @@ # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = Path(__file__).resolve().parent.parent -# os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +CODEX_PATH = BASE_DIR / "codex" +CONFIG_PATH = os.environ.get("CODEX_CONFIG_DIR", Path.cwd() / "config") +CONFIG_PATH.mkdir(exist_ok=True, parents=True) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = "h7+z7h!hp*zvsg@z*9momg85**ogmldelv6$w5&5@f4saj*$rc" +SECRET_KEY_PATH = CONFIG_PATH / "secret_key" +if not SECRET_KEY_PATH.exists(): + from django.core.management.utils import get_random_secret_key -DEV = os.environ.get("DEV") + with open(SECRET_KEY_PATH, "w") as scf: + scf.write(get_random_secret_key()) + +with open(SECRET_KEY_PATH, "r") as scf: + SECRET_KEY = scf.read().strip() + +DEV = bool(os.environ.get("DEV", False)) # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = DEV +DEBUG = DEV or bool(os.environ.get("DEBUG", False)) if DEBUG: LOG_LEVEL = "DEBUG" @@ -66,19 +76,22 @@ "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", +] + +if DEV: + # comes before static apps + INSTALLED_APPS += ["livereload", "debug_toolbar"] + +INSTALLED_APPS += [ "whitenoise.runserver_nostatic", "django.contrib.staticfiles", "rest_framework", "corsheaders", - "webpack_loader", - "codex_api.apps.CodexAPIConfig", - "codex_vue", + "codex", ] -if DEV: - INSTALLED_APPS += ["livereload"] - MIDDLEWARE = [ + "django.middleware.cache.UpdateCacheMiddleware", "corsheaders.middleware.CorsMiddleware", "django.middleware.security.SecurityMiddleware", "whitenoise.middleware.WhiteNoiseMiddleware", @@ -88,10 +101,15 @@ "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", - "codex_api.middleware.TimezoneMiddleware", + "codex.middleware.TimezoneMiddleware", + "django.middleware.cache.FetchFromCacheMiddleware", ] if DEV: - MIDDLEWARE += ["livereload.middleware.LiveReloadScript"] + MIDDLEWARE += [ + "livereload.middleware.LiveReloadScript", + "debug_toolbar.middleware.DebugToolbarMiddleware", + ] + ROOT_URLCONF = "codex.urls" @@ -120,9 +138,12 @@ DATABASES = { "default": { "ENGINE": "django.db.backends.sqlite3", - "NAME": BASE_DIR / "config" / "db.sqlite3", + "NAME": CONFIG_PATH / "db.sqlite3", + "CONN_MAX_AGE": 600, + "OPTIONS": {"timeout": 20}, }, } +SESSION_ENGINE = "django.contrib.sessions.backends.cached_db" # Password validation @@ -156,10 +177,21 @@ # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/3.0/howto/static-files/ -STATIC_ROOT = "static" +STATIC_ROOT = CODEX_PATH / "static_root" STATIC_URL = "static/" -STATICFILES_DIRS = (BASE_DIR / "config/static", BASE_DIR / "codex/static") +CONFIG_STATIC = CONFIG_PATH / "static" +CONFIG_STATIC.mkdir(exist_ok=True, parents=True) +STATICFILES_DIRS = ( + CODEX_PATH / "static_src", + CODEX_PATH / "static_build", + CONFIG_STATIC, +) STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" +WHITENOISE_USE_FINDERS = True # Because we don't collect covers +WHITENOISE_AUTOREFRESH = True # BUG that fails to prefix static otherwise +# BUG Report: https://github.com/evansd/whitenoise/issues/258 +WHITENOISE_KEEP_ONLY_HASHED_FILES = True + SESSION_COOKIE_AGE = 60 * 60 * 24 * 60 # 60 days @@ -173,16 +205,17 @@ ) } -BUNDLE_DIR_NAME = Path("codex_vue") / "static" / "dist" - -if DEV: - CORS_ORIGIN_WHITELIST = ("http://localhost:8080",) CORS_ALLOW_CREDENTIALS = True -WEBPACK_LOADER = { - "DEFAULT": { - "BUNDLE_DIR_NAME": BUNDLE_DIR_NAME, - "STATS_FILE": BASE_DIR / "codex_vue" / "webpack-stats.json", - "CACHE": not DEBUG, +CACHE_PATH = CONFIG_PATH / "cache" +CACHE_PATH.mkdir(exist_ok=True, parents=True) +CACHES = { + "default": { + "BACKEND": "django.core.cache.backends.filebased.FileBasedCache", + "LOCATION": str(CACHE_PATH), } } + +INTERNAL_IPS = [ + "127.0.0.1", +] diff --git a/codex/signals.py b/codex/signals.py new file mode 100644 index 000000000..10005339e --- /dev/null +++ b/codex/signals.py @@ -0,0 +1,19 @@ +"""Signal actions.""" + +from logging import getLogger + +from django.db.backends.signals import connection_created + + +LOG = getLogger(__name__) + + +def activate_wal_journal(sender, connection, **kwargs): + """Enable sqlite WAL journal.""" + if connection.vendor == "sqlite": + cursor = connection.cursor() + cursor.execute("PRAGMA journal_mode=wal;") + LOG.debug("sqlite journal_mode=wal") + + +connection_created.connect(activate_wal_journal) diff --git a/codex/static/admin/js/codex-admin.js b/codex/static/admin/js/codex-admin.js deleted file mode 100644 index 13e04f854..000000000 --- a/codex/static/admin/js/codex-admin.js +++ /dev/null @@ -1,12 +0,0 @@ -/* Dirty hack for django admin's refusal to display non-editable fields */ -const disable = function(el) { - el.setAttribute("readonly", true); - el.setAttribute("disabled", true); -}; - -document.addEventListener("DOMContentLoaded", function() { - let els = document.querySelectorAll(".field-last_scan .vDateField, .field- last_scan .vTimeField"); - Array.from(els).forEach((el) => { - disable(el); - }); -}); diff --git a/codex/static/admin/css/codex-admin.css b/codex/static_src/admin/css/codex-admin.css similarity index 100% rename from codex/static/admin/css/codex-admin.css rename to codex/static_src/admin/css/codex-admin.css diff --git a/codex/static_src/admin/js/codex-admin.js b/codex/static_src/admin/js/codex-admin.js new file mode 100644 index 000000000..ce83ca93f --- /dev/null +++ b/codex/static_src/admin/js/codex-admin.js @@ -0,0 +1,14 @@ +/* Dirty hack for django admin's refusal to display non-editable fields */ +const disable = function (el) { + el.setAttribute("readonly", true); + el.setAttribute("disabled", true); +}; + +document.addEventListener("DOMContentLoaded", function () { + let els = document.querySelectorAll( + ".field-last_scan .vDateField, .field-last_scan .vTimeField" + ); + Array.from(els).forEach((el) => { + disable(el); + }); +}); diff --git a/codex_vue/static/icons/browserconfig.xml b/codex/templates/browserconfig.xml similarity index 51% rename from codex_vue/static/icons/browserconfig.xml rename to codex/templates/browserconfig.xml index c951beb90..4493ebc39 100644 --- a/codex_vue/static/icons/browserconfig.xml +++ b/codex/templates/browserconfig.xml @@ -1,9 +1,10 @@ +{% load static %} - - #da532c + + #000000 diff --git a/codex/templates/index.html b/codex/templates/index.html new file mode 100644 index 000000000..74ceec236 --- /dev/null +++ b/codex/templates/index.html @@ -0,0 +1,63 @@ +{% load static %} + + + + + + + + + + + + + + + + + {% if not DEV %} + + + {% endif %} + Codex + + + + + + +
+ + diff --git a/codex/templates/site.webmanifest b/codex/templates/site.webmanifest new file mode 100644 index 000000000..31fa18f35 --- /dev/null +++ b/codex/templates/site.webmanifest @@ -0,0 +1,19 @@ +{ {% load static %} + "name": "Codex", + "short_name": "Codex", + "icons": [ + { + "src": "{% static 'img/android-chrome-192x192.png' %}", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "{% static 'img/android-chrome-512x512.png' %}", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/codex/urls.py b/codex/urls.py index fb4251aba..34d6e977c 100644 --- a/codex/urls.py +++ b/codex/urls.py @@ -13,16 +13,40 @@ 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ +from django.conf import settings from django.contrib import admin +from django.contrib.staticfiles.storage import staticfiles_storage from django.urls import include from django.urls import path from django.urls import re_path +from django.views.generic.base import RedirectView + +from codex.views.frontend import app +from codex.views.frontend import browserconfig +from codex.views.frontend import webmanifest urlpatterns = [ - path("", include("codex_vue.urls")), - path("api/", include("codex_api.urls")), + path( + "favicon.ico", + RedirectView.as_view(url=staticfiles_storage.url("img/favicon.ico")), + name="favicon", + ), + path( + "robots.txt", + RedirectView.as_view(url=staticfiles_storage.url("robots.txt")), + name="robots", + ), + path("browserconfig.xml", browserconfig, name="browserconfig"), + path("site.webmanifest", webmanifest, name="webmanifest"), + path("api/", include("codex.urls_api")), path("admin/", admin.site.urls, name="admin"), - # Catch all route sends routes to codev_vue - re_path(".*", include("codex_vue.urls")), + path("", app, name="app"), + re_path(".*", app, name="app"), ] + + +if settings.DEBUG: + import debug_toolbar + + urlpatterns = [path("__debug__/", include(debug_toolbar.urls))] + urlpatterns diff --git a/codex_api/urls.py b/codex/urls_api.py similarity index 73% rename from codex_api/urls.py rename to codex/urls_api.py index 33a3502b9..f754baab9 100644 --- a/codex_api/urls.py +++ b/codex/urls_api.py @@ -15,19 +15,18 @@ """ from django.urls import path -from codex_api.views.auth import LoginView -from codex_api.views.auth import LogoutView -from codex_api.views.auth import RegisterView -from codex_api.views.auth import UserView -from codex_api.views.browser import BrowseView -from codex_api.views.metadata import ComicDownloadView -from codex_api.views.metadata import ComicMetadataView -from codex_api.views.metadata import UserBookmarkFinishedView -from codex_api.views.reader import ComicBookmarkView -from codex_api.views.reader import ComicOpenedView -from codex_api.views.reader import ComicPageView -from codex_api.views.reader import ComicReaderView -from codex_api.views.reader import ComicSettingsView +from codex.views.auth import LoginView +from codex.views.auth import LogoutView +from codex.views.auth import RegisterView +from codex.views.auth import UserView +from codex.views.browser import BrowseView +from codex.views.metadata import ComicDownloadView +from codex.views.metadata import ComicMetadataView +from codex.views.metadata import UserBookmarkFinishedView +from codex.views.reader import ComicBookmarkView +from codex.views.reader import ComicOpenedView +from codex.views.reader import ComicPageView +from codex.views.reader import ComicSettingsView # from django.urls import include @@ -50,7 +49,6 @@ ), # # Reader - path("comic//open", ComicReaderView.as_view(), name="comic_reader"), path("comic/", ComicOpenedView.as_view(), name="comic_info"), path( "comic///p.jpg", diff --git a/codex_api/serializers/__init__.py b/codex/views/__init__.py similarity index 100% rename from codex_api/serializers/__init__.py rename to codex/views/__init__.py diff --git a/codex_api/views/auth.py b/codex/views/auth.py similarity index 85% rename from codex_api/views/auth.py rename to codex/views/auth.py index b8cbda7c9..5b7b4f7eb 100644 --- a/codex_api/views/auth.py +++ b/codex/views/auth.py @@ -1,13 +1,6 @@ """Views for browsing comic books.""" import logging -from codex_api.models import AdminFlag -from codex_api.models import UserBookmark -from codex_api.serializers.auth import RegistrationEnabledSerializer -from codex_api.serializers.auth import TimezoneSerializer -from codex_api.serializers.auth import UserCreateSerializer -from codex_api.serializers.auth import UserLoginSerializer -from codex_api.serializers.auth import UserSerializer from django.contrib.auth import authenticate from django.contrib.auth import login from django.contrib.auth import logout @@ -19,6 +12,14 @@ from rest_framework.status import HTTP_201_CREATED from rest_framework.views import APIView +from codex.models import AdminFlag +from codex.models import UserBookmark +from codex.serializers.auth import RegistrationEnabledSerializer +from codex.serializers.auth import TimezoneSerializer +from codex.serializers.auth import UserCreateSerializer +from codex.serializers.auth import UserLoginSerializer +from codex.serializers.auth import UserSerializer + LOG = logging.getLogger(__name__) @@ -43,7 +44,9 @@ def create(self, username, password): def validate(self): """Validate.""" - enable_reg_on = AdminFlag.objects.get(name=AdminFlag.ENABLE_REGISTRATION).on + enable_reg_on = ( + AdminFlag.objects.only("on").get(name=AdminFlag.ENABLE_REGISTRATION).on + ) if not enable_reg_on: raise PermissionDenied("Registration not enabled") serializer = UserCreateSerializer(data=self.request.data) @@ -57,17 +60,19 @@ def validate(self): def post(self, request, *args, **kwargs): """Register a new user.""" serializer = self.validate() + set_timezone(request, serializer) user = self.create( serializer.validated_data["username"], serializer.validated_data["password"] ) - set_timezone(request, serializer) user_serializer = UserSerializer(user) return Response(user_serializer.data, status=HTTP_201_CREATED) def get(self, request, *args, **kwargs): """Just return registration enabled.""" - er_flag = AdminFlag.objects.get(name=AdminFlag.ENABLE_REGISTRATION) - data = {"enableRegistration": er_flag.on} + er_flag_on = ( + AdminFlag.objects.only("on").get(name=AdminFlag.ENABLE_REGISTRATION).on + ) + data = {"enableRegistration": er_flag_on} serializer = RegistrationEnabledSerializer(data) return Response(serializer.data) diff --git a/codex_api/views/browser.py b/codex/views/browser.py similarity index 72% rename from codex_api/views/browser.py rename to codex/views/browser.py index dd4ccc3cb..14024f030 100644 --- a/codex_api/views/browser.py +++ b/codex/views/browser.py @@ -3,7 +3,8 @@ from bidict import bidict from django.db.models import Avg -from django.db.models import BooleanField, CharField +from django.db.models import BooleanField +from django.db.models import CharField from django.db.models import Count from django.db.models import DecimalField from django.db.models import Max @@ -21,21 +22,23 @@ from rest_framework.views import APIView from stringcase import snakecase -from codex_api.choices.model import CharactersFilterChoice -from codex_api.choices.model import DecadeFilterChoice -from codex_api.models import AdminFlag -from codex_api.models import Comic -from codex_api.models import Folder -from codex_api.models import Imprint -from codex_api.models import Library -from codex_api.models import Publisher -from codex_api.models import Series -from codex_api.models import Volume -from codex_api.serializers.browse import BrowseListSerializer -from codex_api.serializers.browse import BrowserOpenedSerializer -from codex_api.serializers.browse import BrowserSettingsSerializer -from codex_api.views.mixins import SessionMixin -from codex_api.views.mixins import UserBookmarkMixin +from codex.choices.model import CharactersFilterChoice +from codex.choices.model import DecadeFilterChoice +from codex.librarian.queue import QUEUE +from codex.librarian.queue import ComicCoverCreateTask +from codex.models import AdminFlag +from codex.models import Comic +from codex.models import Folder +from codex.models import Imprint +from codex.models import Library +from codex.models import Publisher +from codex.models import Series +from codex.models import Volume +from codex.serializers.browse import BrowseListSerializer +from codex.serializers.browse import BrowserOpenedSerializer +from codex.serializers.browse import BrowserSettingsSerializer +from codex.views.mixins import SessionMixin +from codex.views.mixins import UserBookmarkMixin LOG = logging.getLogger(__name__) @@ -57,13 +60,14 @@ class BrowseView(APIView, SessionMixin, UserBookmarkMixin): FOLDER_GROUP: Folder, } ) - GROUP_SHOW_FLAGS = ( - "r", - "p", - "i", - "s", - "v", - ) + GROUP_SHOW_FLAGS = { + # Show flags to root group equivalients + "r": "p", + "p": "i", + "i": "s", + "s": "v", + "v": "c", + } GROUP_RELATION = { "p": "publisher", "i": "imprint", @@ -79,23 +83,60 @@ class BrowseView(APIView, SessionMixin, UserBookmarkMixin): "date": Max, "updated_at": Max, } + DEFAULT_ORDER_KEY = "sort_name" + CHOICES_RELATIONS = ("decade", "characters") + + def get_valid_root_groups(self): + """ + Valid root groups are determined by the Browser Settings. + And offset by one group *above* each show flag. + The volumes root group is always enabled. + """ + valid_groups = [] + + for group_key, show_flag in self.GROUP_SHOW_FLAGS.items(): + enabled = group_key == "v" + enabled = enabled or self.params["show"].get(show_flag) + if enabled: + valid_groups.append(group_key) + + return valid_groups - def get_valid_groups(self): - """Get the valid groups for the settings.""" + def get_valid_nav_groups(self): + """ + Valid nav groups are the root group and below that are also + enabled in browser settings. + """ root_group = self.params["root_group"] valid_groups = [] below_root_group = False + for group_key in self.GROUP_SHOW_FLAGS: - enabled = ( - below_root_group and self.params["show"].get(group_key) - ) or group_key == root_group + if group_key == root_group: + enabled = below_root_group = True + else: + enabled = below_root_group and self.params["show"].get(group_key) if enabled: valid_groups.append(group_key) - if group_key == root_group: - below_root_group = True return valid_groups + def get_model_group(self): + """ + Valid model groups are below the nav group that are also enabled + in browser settings. + """ + nav_group = self.kwargs["group"] + below_nav_group = False + + for group_key in self.valid_nav_groups: + if below_nav_group and self.params["show"].get(group_key): + return group_key + if group_key == nav_group: + below_nav_group = True + + return self.COMIC_GROUP + def filter_by_comic_many_attribute(self, attribute): """Filter by a comic any2many attribute.""" filter_list = self.params["filters"].get(attribute) @@ -133,7 +174,7 @@ def get_bookmark_filter(self): bookmark_filter &= Q(comic__userbookmark__bookmark__gt=0) return bookmark_filter - def get_order_by(self, order_key): + def get_order_by(self, order_key, model=None): """ Create the order_by list. @@ -144,7 +185,11 @@ def get_order_by(self, order_key): order_prefix = "-" else: order_prefix = "" - return [order_prefix + order_key, order_prefix + "pk"] + order_by = [order_prefix + order_key, order_prefix + "pk"] + if model in (Comic, Folder): + # This keeps position stability for duplicate comics & folders + order_by += ["library"] + return order_by def annotate_and_sort(self, obj_list, model, aggregate_filter): """ @@ -196,12 +241,9 @@ def annotate_and_sort(self, obj_list, model, aggregate_filter): # Annote progress obj_list = UserBookmarkMixin.annotate_progress(obj_list) - # TODO it might be nice to add get_unique_name here for - # duplicate objects - # Select comics for the children by an outer ref for annotation # Order the decendent comics by the sort argumentst - order_key = self.params.get("sort_by") + order_key = self.params.get("sort_by", self.DEFAULT_ORDER_KEY) if model != Comic: # Cover Path from sorted children. @@ -212,8 +254,8 @@ def annotate_and_sort(self, obj_list, model, aggregate_filter): comics = comics.filter(model_container_filter) comics = comics.filter(aggregate_filter) order_by = self.get_order_by(order_key) - comics = comics.order_by(*order_by).values("cover_path") - cover_path_subquery = Subquery(comics[:1]) + cover_comic_path = comics.order_by(*order_by).values("cover_path") + cover_path_subquery = Subquery(cover_comic_path[:1]) obj_list = obj_list.annotate(cover_path=cover_path_subquery) # Sortable aggregates @@ -227,7 +269,7 @@ def annotate_and_sort(self, obj_list, model, aggregate_filter): ) # order the containers by the sort arguments - order_by = self.get_order_by(order_key) + order_by = self.get_order_by(order_key, model) obj_list = obj_list.order_by(*order_by) return obj_list @@ -236,7 +278,7 @@ def get_parent_folder_filter(self): """Create the folder and comic object lists.""" pk = self.kwargs.get("pk") if pk: - self.host_folder = Folder.objects.get(pk=pk) + self.host_folder = Folder.objects.select_related("parent_folder").get(pk=pk) else: self.host_folder = None @@ -257,18 +299,8 @@ def set_browse_model(self): group = self.kwargs.get("group") self.group_class = self.GROUP_MODEL[group] - # find for browse groups - valid_model_groups = self.get_valid_groups() - valid_model_groups.append(self.COMIC_GROUP) - found_group = False - for g in valid_model_groups: - child_group = g - if found_group: - break - if g == group: - found_group = True - - self.model = self.GROUP_MODEL[child_group] + model_group = self.get_model_group() + self.model = self.GROUP_MODEL[model_group] def get_browse_container_filter(self): """Get the objects we'll be displaying.""" @@ -292,6 +324,14 @@ def get_query_filters(self, container_filter): object_filter = container_filter & aggregate_filter return object_filter, aggregate_filter + def set_choices_comic_list(self, filters): + """Set the choices comic list for getting choices later.""" + self.choices_comic_list = ( + Comic.objects.filter(filters) + .only(*self.CHOICES_RELATIONS) + .prefetch_related(*self.CHOICES_RELATIONS) + ) + def get_folder_queryset(self): """Create folder queryset.""" object_filter, aggregate_filter = self.get_query_filters( @@ -300,11 +340,10 @@ def get_folder_queryset(self): # Create the main queries with filters folder_list = Folder.objects.filter(object_filter) - comic_list = Comic.objects.filter(object_filter).select_related() + comic_list = Comic.objects.filter(object_filter) + # Create a query for comics used by the model filters - self.choices_comic_list = Comic.objects.filter( - aggregate_filter & self.get_folders_filter() - ) + self.set_choices_comic_list(aggregate_filter & self.get_folders_filter()) # add annotations for display and sorting # and the comic_cover which uses a sort @@ -323,17 +362,17 @@ def get_browse_queryset(self): ) obj_list = self.model.objects.filter(object_filter) # for the model filter choices that don't need annotations - self.choices_comic_list = Comic.objects.filter(object_filter) + self.set_choices_comic_list(object_filter) # obj_list filtering done # Add annotations for display and sorting obj_list = self.annotate_and_sort(obj_list, self.model, aggregate_filter) if self.model == Comic: - container_list = tuple() + container_list = Volume.objects.none() comic_list = obj_list else: container_list = obj_list - comic_list = tuple() + comic_list = Comic.objects.none() return container_list, comic_list def get_folder_up_route(self): @@ -372,7 +411,7 @@ def get_browse_up_route(self): # Ancestor group ancestor_group = None - for group_key in self.valid_groups: + for group_key in self.valid_nav_groups: if group_key == group: break ancestor_group = group_key @@ -408,6 +447,9 @@ def get_context(self): if self.params.get("root_group") == self.FOLDER_GROUP: up_group, up_pk = self.get_folder_up_route() browse_title = self.get_folder_title() + self.comic_list = self.comic_list.select_related( + "myself", "volume", "series" + ) else: self.set_group_instance() up_group, up_pk = self.get_browse_up_route() @@ -416,7 +458,7 @@ def get_context(self): if up_group is not None and up_pk is not None: up_route = {"group": up_group, "pk": up_pk} else: - up_route = None + up_route = {} decade_filter_choices = DecadeFilterChoice.get_vue_choices( self.choices_comic_list @@ -425,14 +467,9 @@ def get_context(self): self.choices_comic_list ) - admin_flags = AdminFlag.objects.filter(name__in=AdminFlag.FLAG_NAMES).values( - "name", "on" - ) - admin = {} - for obj in admin_flags: - admin[obj.get("name")] = obj.get("on") + efv_flag = AdminFlag.objects.only("on").get(name=AdminFlag.ENABLE_FOLDER_VIEW) - efv_flag = AdminFlag.objects.get(name=AdminFlag.ENABLE_FOLDER_VIEW) + libraries_exist = Library.objects.exists() context = { "upRoute": up_route, @@ -444,14 +481,20 @@ def get_context(self): "characters": characters_filter_choices, "enableFolderView": efv_flag.on, }, + "librariesExist": libraries_exist, } return context + def raise_valid_route(self, message): + """403 should redirect to the valid group on the client side.""" + valid_group = self.valid_nav_groups[0] + raise PermissionDenied({"group": valid_group, "message": message}) + def validate_folder_settings(self): """Check that all the view variables for folder mode are set right.""" - if not AdminFlag.objects.get(name=AdminFlag.ENABLE_FOLDER_VIEW).on: - # 403 should redirect on the client side. - raise PermissionDenied("folder view disabled") + if not AdminFlag.objects.only("on").get(name=AdminFlag.ENABLE_FOLDER_VIEW).on: + self.valid_nav_groups = self.get_valid_nav_groups() + raise self.raise_valid_route("folder view disabled") def validate_browse_settings(self): """Check that all the view variables for browser mode are set right.""" @@ -461,26 +504,19 @@ def validate_browse_settings(self): if root_group == self.FOLDER_GROUP: self.params["root_group"] = root_group = group LOG.warn(f"Switched root group from {self.FOLDER_GROUP} to {group}") - self.valid_groups = self.get_valid_groups() - - for valid_group in self.valid_groups: - if valid_group == root_group: - break - if valid_group == group: - self.params["root_group"] = root_group = group - LOG.warn( - f"Group '{group}' was a parent of root group " - f"'{root_group}'. Reset root group to '{group}'." - ) - self.valid_groups = self.get_valid_groups() - break + else: + valid_root_groups = self.get_valid_root_groups() + if root_group not in valid_root_groups: + if group in valid_root_groups: + self.params["root_group"] = root_group = group + else: + self.params["root_group"] = valid_root_groups[0] + LOG.warn(f"Reset root group to {self.params['root_group']}") # Validate Group - if group not in self.valid_groups: - exc = PermissionDenied(detail=f"Asked to show disabled group {group}") - LOG.exception(exc) - # 403 should redirect on the client side. - raise exc + self.valid_nav_groups = self.get_valid_nav_groups() + if group not in self.valid_nav_groups: + self.raise_valid_route(f"Asked to show disabled group {group}") def validate_put(self, data): """Validate submitted settings.""" @@ -497,6 +533,23 @@ def validate_put(self, data): snake_key = snakecase(key) self.params[snake_key] = value + @staticmethod + def ensure_covers(container_list, comic_list): + """Generate cover thumbs if they dont' exist.""" + # XXX This hits the db a second time for all containers & comics + # Might be better to use the same query we send to for + # serialization + for obj in container_list: + LOG.debug(f"ensure container cover {obj.cover_path}") + task = ComicCoverCreateTask(None, obj.cover_path) + QUEUE.put(task) + + comic_list = comic_list.only("path", "cover_path") + for obj in comic_list: + LOG.debug(f"ensure comic cover {obj.path} {obj.cover_path}") + task = ComicCoverCreateTask(obj.path, obj.cover_path) + QUEUE.put(task) + def get_queryset(self): """Validate settings and get the queryset.""" if self.kwargs.get("group") == self.FOLDER_GROUP: @@ -506,11 +559,13 @@ def get_queryset(self): self.validate_browse_settings() self.container_list, self.comic_list = self.get_browse_queryset() + # kick off cover ensure as soon as we have the final lists. + self.ensure_covers(self.container_list, self.comic_list) + self.request.session[self.BROWSE_KEY] = self.params self.request.session.save() - context = self.get_context() - return context + return self.get_context() def put(self, request, *args, **kwargs): """Create the view.""" @@ -528,7 +583,6 @@ def get(self, request, *args, **kwargs): context = self.get_queryset() filters = self.params["filters"] - libraries_exist = Library.objects.all().exists() data = { "settings": { "filters": { @@ -542,7 +596,6 @@ def get(self, request, *args, **kwargs): "show": self.params.get("show"), }, "browseList": context, - "librariesExist": libraries_exist, } serializer = BrowserOpenedSerializer(data) diff --git a/codex/views/frontend.py b/codex/views/frontend.py new file mode 100644 index 000000000..7c0aa84e6 --- /dev/null +++ b/codex/views/frontend.py @@ -0,0 +1,22 @@ +"""Frontend views.""" +from django.shortcuts import render +from django.urls import get_script_prefix + +from codex.settings import DEV + + +def app(request): + """Serve the main application page.""" + return render( + request, "index.html", context={"root_path": get_script_prefix(), "DEV": DEV} + ) + + +def webmanifest(request): + """Serve the webmanifest spec. For android and chrome.""" + return render(request, "site.webmanifest", content_type="application/manifest+json") + + +def browserconfig(request): + """Serve browserconfig xml for microsoft.""" + return render(request, "browserconfig.xml", content_type="text/xml") diff --git a/codex_api/views/metadata.py b/codex/views/metadata.py similarity index 84% rename from codex_api/views/metadata.py rename to codex/views/metadata.py index 83d37c007..e3e258c67 100644 --- a/codex_api/views/metadata.py +++ b/codex/views/metadata.py @@ -8,12 +8,12 @@ from rest_framework.response import Response from rest_framework.views import APIView -from codex_api.models import Comic -from codex_api.serializers.metadata import ComicSerializer -from codex_api.serializers.metadata import UserBookmarkFinishedSerializer -from codex_api.views.browser import BrowseView -from codex_api.views.mixins import SessionMixin -from codex_api.views.mixins import UserBookmarkMixin +from codex.models import Comic +from codex.serializers.metadata import ComicSerializer +from codex.serializers.metadata import UserBookmarkFinishedSerializer +from codex.views.browser import BrowseView +from codex.views.mixins import SessionMixin +from codex.views.mixins import UserBookmarkMixin LOG = logging.getLogger(__name__) @@ -26,7 +26,7 @@ def get(self, request, *args, **kwargs): """Download a comic archive.""" pk = kwargs.get("pk") try: - comic_path = Comic.objects.get(pk=pk).path + comic_path = Comic.objects.only("path").get(pk=pk).path except Comic.DoesNotExist: raise Http404(f"Comic {pk} not not found.") @@ -46,7 +46,7 @@ def patch(self, request, *args, **kwargs): serializer.is_valid(raise_exception=True) relation = BrowseView.GROUP_RELATION.get(browse_type) - comics = Comic.objects.filter(**{relation: pk}) + comics = Comic.objects.filter(**{relation: pk}).only("pk") updates = {"finished": serializer.validated_data.get("finished")} for comic in comics: @@ -84,6 +84,6 @@ def get(self, request, *args, **kwargs): comic = self.annotate_progress(comic) pk = kwargs.get("pk") - res = comic.select_related().get(pk=pk) + res = comic.select_related().prefetch_related().get(pk=pk) serializer = ComicSerializer(res) return Response(serializer.data) diff --git a/codex_api/views/mixins.py b/codex/views/mixins.py similarity index 92% rename from codex_api/views/mixins.py rename to codex/views/mixins.py index 6cd79e55d..da6ba2a8c 100644 --- a/codex_api/views/mixins.py +++ b/codex/views/mixins.py @@ -9,9 +9,9 @@ from django.db.models import Value from django.db.models.functions import Coalesce -from codex_api.choices.static import DEFAULTS -from codex_api.models import Comic -from codex_api.models import UserBookmark +from codex.choices.static import DEFAULTS +from codex.models import Comic +from codex.models import UserBookmark class SessionMixin: @@ -33,9 +33,7 @@ class SessionMixin: "sort_reverse": False, "show": DEFAULTS["show"], }, - READER_KEY: { - "defaults": {"fit_to": DEFAULTS["fitTo"], "two_pages": False} - }, + READER_KEY: {"defaults": {"fit_to": DEFAULTS["fitTo"], "two_pages": False}}, } def get_session(self, session_key): @@ -76,7 +74,7 @@ def _get_user_bookmark_search_kwargs(self, comic=None, comic_pk=None): search_kwargs["user"] = self.request.user else: try: - session = Session.objects.get( + session = Session.objects.only("pk", "session_key").get( session_key=self.request.session.session_key ) except Session.DoesNotExist: @@ -85,7 +83,7 @@ def _get_user_bookmark_search_kwargs(self, comic=None, comic_pk=None): # in the db before looking it up. session = Session.objects.get( session_key=self.request.session.session_key - ) + ).only("pk", "session_key") search_kwargs["session"] = session return search_kwargs @@ -102,7 +100,7 @@ def get_user_bookmark(self, pk): def update_user_bookmark(self, updates, comic=None, pk=None): """Update a user bookmark.""" if comic is None: - comic = Comic.objects.get(pk=pk) + comic = Comic.objects.only("pk").get(pk=pk) search_kwargs = self._get_user_bookmark_search_kwargs(comic) if updates.get("bookmark") == comic.max_page: # Auto finish on bookmark last page diff --git a/codex_api/views/reader.py b/codex/views/reader.py similarity index 82% rename from codex_api/views/reader.py rename to codex/views/reader.py index 185c53b9c..10bcfc9e9 100644 --- a/codex_api/views/reader.py +++ b/codex/views/reader.py @@ -1,22 +1,22 @@ """Views for reading comic books.""" import logging +from comicbox.comic_archive import ComicArchive from django.http import HttpResponse +from rest_framework.exceptions import NotFound from rest_framework.response import Response from rest_framework.views import APIView from stringcase import camelcase from stringcase import snakecase -from codex_api.models import Comic -from codex_api.serializers.read import ComicReaderInfoSerializer -from codex_api.serializers.read import ComicReaderSettingsSerializer -from codex_api.views.mixins import SessionMixin -from codex_api.views.mixins import UserBookmarkMixin -from comicbox.comic_archive import ComicArchive +from codex.models import Comic +from codex.serializers.read import ComicReaderInfoSerializer +from codex.serializers.read import ComicReaderSettingsSerializer +from codex.views.mixins import SessionMixin +from codex.views.mixins import UserBookmarkMixin LOG = logging.getLogger(__name__) -NOTFOUND_IMG_FN = "static/404.png" class ComicOpenedView(APIView, SessionMixin, UserBookmarkMixin): @@ -32,17 +32,16 @@ def get_settings(self): defaults = reader_session.get( "defaults", self.SESSION_DEFAULTS[self.READER_KEY]["defaults"] ) + pk = self.kwargs.get("pk") + ub = self.get_user_bookmark(pk) for key in self.SETTINGS_KEYS: camel_key = camelcase(key) settings["globl"][camel_key] = defaults.get(key) - - pk = self.kwargs.get("pk") - ub = self.get_user_bookmark(pk) - if ub: - settings["local"] = {} - for key in self.SETTINGS_KEYS: - camel_key = camelcase(key) - settings["local"][camel_key] = getattr(ub, key) + if ub: + val = getattr(ub, key) + else: + val = None + settings["local"][camel_key] = val return settings @@ -55,8 +54,10 @@ def get_prev_next_comics(self): might be even more expensive. """ pk = self.kwargs.get("pk") - comics = Comic.objects.filter(series__comic=pk).order_by( - "series__name", "volume__name", "issue" + comics = ( + Comic.objects.filter(series__comic=pk) + .order_by("series__name", "volume__name", "issue") + .only("pk", "max_page") ) current_comic = None @@ -70,7 +71,7 @@ def get_prev_next_comics(self): elif prev_route is None: # Haven't matched yet, so set the previous comic prev_route = {"pk": comic.pk, "pageNumber": comic.max_page} - routes = {"prevComicPage": prev_route, "nextComicPage": next_route} + routes = {"prevBook": prev_route, "nextBook": next_route} return current_comic, routes def get(self, request, *args, **kwargs): @@ -91,19 +92,13 @@ def get(self, request, *args, **kwargs): return Response(serializer.data) -class ComicReaderView(ComicOpenedView): - """Get context for displaying comic reader toolbar.""" - - pass - - class ComicPageView(APIView): """Display a comic page from the archive itself.""" def get(self, request, *args, **kwargs): """Get the comic page from the archive.""" pk = self.kwargs.get("pk") - comic = Comic.objects.get(pk=pk) + comic = Comic.objects.only("path").get(pk=pk) try: car = ComicArchive(comic.path) page_num = self.kwargs.get("page_num") @@ -111,8 +106,7 @@ def get(self, request, *args, **kwargs): return HttpResponse(page_image, content_type="image/jpeg") except Exception as exc: LOG.exception(exc) - page_image = open(NOTFOUND_IMG_FN, "rb") - return HttpResponse(page_image, content_type="image/png") + raise NotFound(detail="comic page not found") class ComicBookmarkView(APIView, UserBookmarkMixin): diff --git a/codex_api/websocket.py b/codex/websocket_server.py similarity index 92% rename from codex_api/websocket.py rename to codex/websocket_server.py index fae33b893..db93f16c9 100644 --- a/codex_api/websocket.py +++ b/codex/websocket_server.py @@ -1,15 +1,16 @@ """Websocket Consumers.""" -import multiprocessing import random import time from logging import getLogger +from multiprocessing import Value from queue import Queue from threading import Thread import simplejson as json from asgiref.sync import async_to_sync +from django.core.cache import cache from simplejson import JSONDecodeError @@ -22,12 +23,13 @@ UNSUBSCRIBE_MSG = "unsubscribe" BROADCAST_MSG = "broadcast" # Shared memory broadcast security -BROADCAST_SECRET = multiprocessing.Value("i", random.randint(0, 100)) +BROADCAST_SECRET = Value("i", random.randint(0, 100)) +LIBRARY_CHANGED_MSG = "libraryChanged" # Flood control MESSAGE_QUEUE = Queue() SHUTDOWN_MSG = "shutdown" -FLOOD_DELAY = 1 # wait a second before broadcasting +FLOOD_DELAY = 2 # wait seconds before broadcasting def get_send_msg(message): @@ -84,6 +86,7 @@ def flood_control_worker(): if MESSAGE_QUEUE.empty(): wait_left = timestamp + FLOOD_DELAY - time.time() if wait_left <= 0: + cache.clear() msg = {"text": message} msg.update(WS_SEND_MSG) for send in BROADCAST_CONNS: diff --git a/codex/wsgi.py b/codex/wsgi.py index 8676f6741..42c00e013 100644 --- a/codex/wsgi.py +++ b/codex/wsgi.py @@ -1,5 +1,5 @@ """ -WSGI config for codex project. +WSGI config for codex project. Unused. For testing only. It exposes the WSGI callable as a module-level variable named ``application``. @@ -19,7 +19,7 @@ def start_daemons(): """Delay import until settings environment set.""" - from codex_api.library.daemon import start_daemons + from codex.librarian.daemon import start_daemons start_daemons() diff --git a/codex_api/apps.py b/codex_api/apps.py deleted file mode 100644 index c2a502a21..000000000 --- a/codex_api/apps.py +++ /dev/null @@ -1,19 +0,0 @@ -"""App Config.""" - -from logging import getLogger - -from django.apps import AppConfig - - -LOG = getLogger(__name__) - - -class CodexAPIConfig(AppConfig): - """Application config, mostly for startup tasks.""" - - name = "codex_api" - verbose_name = "Codex API" - - def ready(self): - """Do this once when the app is ready.""" - self.get_model("AdminFlag").init_all_flags() diff --git a/codex_api/migrations/0001_initial.py b/codex_api/migrations/0001_initial.py deleted file mode 100644 index ae89d4338..000000000 --- a/codex_api/migrations/0001_initial.py +++ /dev/null @@ -1,338 +0,0 @@ -# Generated by Django 3.1a1 on 2020-06-12 22:41 - -import codex_api.models -import datetime -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('sessions', '0001_initial'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='Character', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=32)), - ], - options={ - 'abstract': False, - 'unique_together': {('name',)}, - }, - ), - migrations.CreateModel( - name='Imprint', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('is_default', models.BooleanField(default=False)), - ('sort_name', models.CharField(max_length=32)), - ('name', models.CharField(default='Main Imprint', max_length=32)), - ], - ), - migrations.CreateModel( - name='Library', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('path', models.CharField(max_length=128, unique=True, validators=[codex_api.models.validate_dir_exists])), - ('enable_watch', models.BooleanField(default=True)), - ('enable_scan_cron', models.BooleanField(default=True)), - ('scan_frequency', models.DurationField(default=datetime.timedelta(seconds=43200))), - ('last_scan', models.DateTimeField(null=True)), - ('scan_in_progress', models.BooleanField(default=False)), - ('schema_version', models.PositiveSmallIntegerField(default=0)), - ], - options={ - 'abstract': False, - }, - ), - migrations.CreateModel( - name='Publisher', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('is_default', models.BooleanField(default=False)), - ('sort_name', models.CharField(max_length=32)), - ('name', models.CharField(default='No Publisher', max_length=32)), - ], - options={ - 'unique_together': {('name', 'is_default')}, - }, - ), - migrations.CreateModel( - name='Series', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('is_default', models.BooleanField(default=False)), - ('sort_name', models.CharField(max_length=32)), - ('name', models.CharField(default='Default Series', max_length=32)), - ('volume_count', models.PositiveSmallIntegerField(null=True)), - ('imprint', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='codex_api.imprint')), - ('publisher', models.ForeignKey(on_delete=codex_api.models.Publisher.get_default_publisher, to='codex_api.publisher')), - ], - options={ - 'unique_together': {('name', 'imprint', 'is_default')}, - }, - ), - migrations.CreateModel( - name='Volume', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('is_default', models.BooleanField(default=False)), - ('sort_name', models.CharField(max_length=32)), - ('name', models.CharField(default='', max_length=32)), - ('issue_count', models.DecimalField(decimal_places=2, max_digits=6, null=True)), - ('imprint', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='codex_api.imprint')), - ('publisher', models.ForeignKey(on_delete=codex_api.models.Publisher.get_default_publisher, to='codex_api.publisher')), - ('series', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='codex_api.series')), - ], - options={ - 'unique_together': {('name', 'series', 'is_default')}, - }, - ), - migrations.CreateModel( - name='Team', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=32)), - ], - options={ - 'abstract': False, - 'unique_together': {('name',)}, - }, - ), - migrations.CreateModel( - name='Tag', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=32)), - ], - options={ - 'abstract': False, - 'unique_together': {('name',)}, - }, - ), - migrations.CreateModel( - name='StoryArc', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=32)), - ], - options={ - 'abstract': False, - 'unique_together': {('name',)}, - }, - ), - migrations.CreateModel( - name='SeriesGroup', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=32)), - ], - options={ - 'abstract': False, - 'unique_together': {('name',)}, - }, - ), - migrations.CreateModel( - name='Location', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=32)), - ], - options={ - 'abstract': False, - 'unique_together': {('name',)}, - }, - ), - migrations.AddField( - model_name='imprint', - name='publisher', - field=models.ForeignKey(on_delete=models.SET(codex_api.models.Publisher.get_default_publisher), to='codex_api.publisher'), - ), - migrations.CreateModel( - name='Genre', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=32)), - ], - options={ - 'abstract': False, - 'unique_together': {('name',)}, - }, - ), - migrations.CreateModel( - name='Folder', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=32)), - ('path', models.CharField(max_length=128, validators=[codex_api.models.validate_dir_exists])), - ('sort_name', models.CharField(max_length=32)), - ('library', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='codex_api.library')), - ('parent_folder', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='codex_api.folder')), - ], - options={ - 'unique_together': {('library', 'path')}, - }, - ), - migrations.CreateModel( - name='CreditRole', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=32)), - ], - options={ - 'abstract': False, - 'unique_together': {('name',)}, - }, - ), - migrations.CreateModel( - name='CreditPerson', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=32)), - ], - options={ - 'abstract': False, - 'unique_together': {('name',)}, - }, - ), - migrations.CreateModel( - name='Credit', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='codex_api.creditperson')), - ('role', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='codex_api.creditrole')), - ], - options={ - 'unique_together': {('person', 'role')}, - }, - ), - migrations.CreateModel( - name='Comic', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('path', models.CharField(max_length=128)), - ('issue', models.DecimalField(decimal_places=2, default=0.0, max_digits=6)), - ('title', models.CharField(max_length=64, null=True)), - ('year', models.PositiveSmallIntegerField(null=True)), - ('month', models.PositiveSmallIntegerField(null=True)), - ('day', models.PositiveSmallIntegerField(null=True)), - ('summary', models.TextField(null=True)), - ('notes', models.TextField(null=True)), - ('description', models.TextField(null=True)), - ('critical_rating', models.CharField(max_length=32, null=True)), - ('maturity_rating', models.CharField(max_length=32, null=True)), - ('user_rating', models.CharField(max_length=32, null=True)), - ('country', models.CharField(max_length=32, null=True)), - ('language', models.CharField(max_length=16, null=True)), - ('page_count', models.PositiveSmallIntegerField(default=0)), - ('cover_image', models.CharField(max_length=64, null=True)), - ('read_ltr', models.BooleanField(default=True)), - ('web', models.URLField(null=True)), - ('format', models.CharField(max_length=16, null=True)), - ('scan_info', models.CharField(max_length=32, null=True)), - ('sort_name', models.CharField(max_length=32)), - ('date', models.DateField(null=True)), - ('decade', models.PositiveSmallIntegerField(null=True)), - ('size', models.PositiveSmallIntegerField()), - ('max_page', models.PositiveSmallIntegerField(default=0)), - ('cover_path', models.CharField(default='codex/default_cover.png', max_length=32)), - ('characters', models.ManyToManyField(to='codex_api.Character')), - ('credits', models.ManyToManyField(to='codex_api.Credit')), - ('folder', models.ManyToManyField(to='codex_api.Folder')), - ('genres', models.ManyToManyField(to='codex_api.Genre')), - ('imprint', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='codex_api.imprint')), - ('library', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='codex_api.library')), - ('locations', models.ManyToManyField(to='codex_api.Location')), - ('myself', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='comic', to='codex_api.comic')), - ('parent_folder', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='comic_in', to='codex_api.folder')), - ('publisher', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='codex_api.publisher')), - ('series', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='codex_api.series')), - ('series_groups', models.ManyToManyField(to='codex_api.SeriesGroup')), - ('story_arcs', models.ManyToManyField(to='codex_api.StoryArc')), - ('tags', models.ManyToManyField(to='codex_api.Tag')), - ('teams', models.ManyToManyField(to='codex_api.Team')), - ('volume', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='codex_api.volume')), - ], - options={ - 'unique_together': {('path', 'volume', 'year', 'issue')}, - }, - ), - migrations.CreateModel( - name='AdminFlag', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=32)), - ('on', models.BooleanField(default=True)), - ], - options={ - 'abstract': False, - 'unique_together': {('name',)}, - }, - ), - migrations.CreateModel( - name='UserBookmark', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('bookmark', models.PositiveSmallIntegerField(null=True)), - ('finished', models.BooleanField(default=False)), - ('fit_to', models.CharField(default=None, max_length=6, null=True, validators=[codex_api.models.validate_fit_to_choice])), - ('two_pages', models.BooleanField(default=None, null=True)), - ('comic', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='codex_api.comic')), - ('session', models.ForeignKey(null=True, on_delete=codex_api.models.cascade_if_user_null, to='sessions.session')), - ('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - options={ - 'unique_together': {('user', 'session', 'comic')}, - }, - ), - migrations.AlterUniqueTogether( - name='imprint', - unique_together={('name', 'publisher', 'is_default')}, - ), - ] diff --git a/codex_api/static/404.png b/codex_api/static/404.png deleted file mode 100644 index 14c740f051ba4e57f31df5f3ab88ec49cbe46f1b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^6+pa&g&9b$P57z@r1%4TLR^9LyLazCeE9J1-@pI= z|1<8|cL*rt=jq}YQW5v|mZKnp0uRf^%?<1-3m87E=j4C;;q<@93B}S+dy2HJpFS(+ jIc$IreNVf1`vv0)vAo6erd;<1n#|zo>gTe~DWM4f6w5tP diff --git a/codex_api/views/__init__.py b/codex_api/views/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/codex_vue/.gitignore b/codex_vue/.gitignore deleted file mode 100644 index 35763fbc1..000000000 --- a/codex_vue/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -.DS_Store -node_modules -static/dist -webpack-stats.json - -# 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? - -# Caches -.eslintcache diff --git a/codex_vue/.prettierignore b/codex_vue/.prettierignore deleted file mode 100644 index 775848dd6..000000000 --- a/codex_vue/.prettierignore +++ /dev/null @@ -1,3 +0,0 @@ -static/dist -templates -public/index.html diff --git a/codex_vue/__init__.py b/codex_vue/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/codex_vue/apps.py b/codex_vue/apps.py deleted file mode 100644 index 57d489ca1..000000000 --- a/codex_vue/apps.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.apps import AppConfig - - -class CodexVueConfig(AppConfig): - name = "codex_vue" diff --git a/codex_vue/package.json b/codex_vue/package.json deleted file mode 100644 index 8356c05a0..000000000 --- a/codex_vue/package.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "name": "codex_vue", - "version": "0.1.0", - "private": true, - "description": "ui for codex api", - "scripts": { - "build": "vue-cli-service build --modern", - "dev": "vue-cli-service build --watch", - "lint": "vue-cli-service lint", - "serve": "vue-cli-service serve" - }, - "dependencies": { - "axios": "^0.19.2", - "core-js": "^3.6.4", - "normalize.css": "^8.0.1", - "reconnecting-websocket": "^4.4.0", - "vue": "^2.6.11", - "vue-router": "^3.3.4", - "vue2-filters": "^0.11.0", - "vuetify": "^2.3.3", - "vuex": "^3.5.1" - }, - "devDependencies": { - "@mdi/font": "^5.3.45", - "@mdi/js": "^5.3.45", - "@vue/cli-plugin-babel": "~4.3.0", - "@vue/cli-plugin-eslint": "~4.3.0", - "@vue/cli-plugin-vuex": "~4.3.0", - "@vue/cli-service": "~4.3.0", - "@vue/eslint-config-prettier": "^6.0.0", - "babel-eslint": "^10.1.0", - "eslint": "^6.7.2", - "eslint-config-adjunct": "^4.8.4", - "eslint-config-prettier": "^6.11.0", - "eslint-plugin-array-func": "^3.1.6", - "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-html": "^6.0.2", - "eslint-plugin-json": "^2.1.1", - "eslint-plugin-json-format": "^2.0.1", - "eslint-plugin-markdown": "^1.0.2", - "eslint-plugin-no-constructor-bind": "^2.0.2", - "eslint-plugin-no-secrets": "^0.5.4", - "eslint-plugin-no-unsanitized": "^3.1.2", - "eslint-plugin-no-use-extend-native": "^0.5.0", - "eslint-plugin-only-warn": "^1.0.2", - "eslint-plugin-optimize-regex": "^1.2.0", - "eslint-plugin-prettier": "^3.1.4", - "eslint-plugin-promise": "^4.2.1", - "eslint-plugin-scanjs-rules": "^0.2.1", - "eslint-plugin-security": "^1.4.0", - "eslint-plugin-simple-import-sort": "^5.0.3", - "eslint-plugin-sonarjs": "^0.5.0", - "eslint-plugin-switch-case": "^1.1.2", - "eslint-plugin-unicorn": "^19.0.1", - "eslint-plugin-vue": "^6.2.2", - "eslint-plugin-vue-scoped-css": "^0.5.0", - "prettier": "^2.0.5", - "prettier-plugin-package": "^1.0.0", - "sass": "^1.26.9", - "sass-loader": "^8.0.2", - "typeface-roboto": "0.0.75", - "vue-cli-plugin-vuetify": "^2.0.6", - "vue-template-compiler": "^2.6.11", - "vuetify-loader": "^1.5.0", - "webpack-bundle-tracker": "^0.4.3" - }, - "prettier": { - "trailingComma": "es5", - "arrowParens": "always", - "tabWidth": 2 - } -} diff --git a/codex_vue/public/css/global.css b/codex_vue/public/css/global.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/codex_vue/public/index.html b/codex_vue/public/index.html deleted file mode 120000 index 27120c26d..000000000 --- a/codex_vue/public/index.html +++ /dev/null @@ -1 +0,0 @@ -../templates/codex_vue/index.html \ No newline at end of file diff --git a/codex_vue/public/index.html.webpack b/codex_vue/public/index.html.webpack deleted file mode 100644 index 4a74d4a95..000000000 --- a/codex_vue/public/index.html.webpack +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - <%= htmlWebpackPlugin.options.title %> - - - - - -
-
- -
-
-
- - diff --git a/codex_vue/src/components/book-cover.vue b/codex_vue/src/components/book-cover.vue deleted file mode 100644 index dc8175540..000000000 --- a/codex_vue/src/components/book-cover.vue +++ /dev/null @@ -1,51 +0,0 @@ - - - - - diff --git a/codex_vue/src/public-path.js b/codex_vue/src/public-path.js deleted file mode 100644 index cc49b94ad..000000000 --- a/codex_vue/src/public-path.js +++ /dev/null @@ -1,15 +0,0 @@ -if (window.fetch) { - fetch(location, { method: "HEAD" }) - .then((request) => { - request.headers.forEach((key, value) => { - if (["Daphne-Root-Path"].includes(key)) { - /* global __webpack_public_path__:writable */ - __webpack_public_path__ = __webpack_public_path__ + value; - } - }); - return undefined; - }) - .catch((error) => { - console.error(error); - }); -} diff --git a/codex_vue/static/favicon.ico b/codex_vue/static/favicon.ico deleted file mode 120000 index 66ca2ed95..000000000 --- a/codex_vue/static/favicon.ico +++ /dev/null @@ -1 +0,0 @@ -../../codex_api/static/codex/codex-512.jpg \ No newline at end of file diff --git a/codex_vue/static/icons/favicon.ico b/codex_vue/static/icons/favicon.ico deleted file mode 100644 index 3dfca9b3003f6c76c463e67c507dd9456dc73d92..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12014 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 - - - -Created by potrace 1.11, written by Peter Selinger 2001-2013 - - - - - - - - - - - diff --git a/codex_vue/static/icons/site.webmanifest b/codex_vue/static/icons/site.webmanifest deleted file mode 100644 index dd2065ffa..000000000 --- a/codex_vue/static/icons/site.webmanifest +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "", - "short_name": "", - "icons": [ - { - "src": "/static/icons/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/static/icons/android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "theme_color": "#000000", - "background_color": "#000000", - "display": "standalone" -} diff --git a/codex_vue/templates/codex_vue/index.html b/codex_vue/templates/codex_vue/index.html deleted file mode 100644 index 6923b4ae9..000000000 --- a/codex_vue/templates/codex_vue/index.html +++ /dev/null @@ -1,49 +0,0 @@ -{% load render_bundle from webpack_loader %} -{% load webpack_static from webpack_loader %} - - - - - - - {# favicons #} - - - - - - - - - - Codex - - - - {% render_bundle 'chunk-vendors' 'css' %} - {% render_bundle 'app' 'css' %} - {% render_bundle 'chunk-vendors' 'js' attrs='defer charset="utf-8"' %} - {% render_bundle 'app' 'js' attrs='defer charset="utf-8"' %} - - - -
- - diff --git a/codex_vue/tests.py b/codex_vue/tests.py deleted file mode 100644 index 7c72b39d1..000000000 --- a/codex_vue/tests.py +++ /dev/null @@ -1,4 +0,0 @@ -from django.test import TestCase - - -# Create your tests here. diff --git a/codex_vue/urls.py b/codex_vue/urls.py deleted file mode 100644 index bd9c05176..000000000 --- a/codex_vue/urls.py +++ /dev/null @@ -1,18 +0,0 @@ -"""Urls for the serving the vue apps.""" -from django.contrib.staticfiles.storage import staticfiles_storage -from django.urls import path -from django.views.generic.base import RedirectView - -from codex_vue.views import app - - -urlpatterns = [ - path( - "favicon.ico", - RedirectView.as_view( - url=staticfiles_storage.url("favicon.ico"), permanent=False - ), - name="favicon", - ), - path("", app, name="app"), -] diff --git a/codex_vue/views.py b/codex_vue/views.py deleted file mode 100644 index f592679ba..000000000 --- a/codex_vue/views.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.shortcuts import render - - -def app(request): - return render(request, "codex_vue/index.html") diff --git a/codex_vue/vue.config.js b/codex_vue/vue.config.js deleted file mode 100644 index 66aa18ce4..000000000 --- a/codex_vue/vue.config.js +++ /dev/null @@ -1,15 +0,0 @@ -const BundleTracker = require("webpack-bundle-tracker"); - -const DEV = process.env.NODE_ENV === "development"; - -const STATIC_DIR = "static/dist/"; - -module.exports = { - outputDir: STATIC_DIR, - productionSourceMap: DEV, - configureWebpack: { - plugins: [new BundleTracker()], - }, - transpileDependencies: ["vuetify"], - publicPath: `/${STATIC_DIR}`, -}; diff --git a/collectstatic.sh b/collectstatic.sh new file mode 100755 index 000000000..4312b0509 --- /dev/null +++ b/collectstatic.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# Run the django collectstatic command to collect static files from all +# locations specified in settings.STATIC_DIRS and place them in +# settings.STATIC_ROOT for production builds. +STATIC_PROD=$(poetry run python -c 'from codex.settings import STATIC_ROOT; print(STATIC_ROOT)') +STATIC_CONFIG=$(poetry run python -c 'from codex.settings import CONFIG_STATIC; print(CONFIG_STATIC)') +rm -rf "$STATIC_PROD" +mkdir -p "$STATIC_PROD" "$STATIC_CONFIG" +./pm collectstatic --clear --ignore covers --no-input diff --git a/dev-frontend.sh b/dev-frontend.sh new file mode 100755 index 000000000..89a7fc121 --- /dev/null +++ b/dev-frontend.sh @@ -0,0 +1,4 @@ +#!/bin/sh +# Run the live reloading front end development server +cd "$(dirname "$0")/frontend" || exit 1 +npm run dev diff --git a/dev-livereload.sh b/dev-livereload.sh new file mode 100755 index 000000000..da5e371c6 --- /dev/null +++ b/dev-livereload.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# Run the django livereload app to trigger reloading the frontennd when the +# api restarts +cd "$(dirname "$0")" || exit 1 +printf "Waiting for dajngo server to start..." +until lsof -i -P -n | grep -q '9810.*LISTEN'; do + sleep 1 + printf "." +done +printf "\\n" +DEV=1 ./pm livereload diff --git a/dev-reverse-proxy.sh b/dev-reverse-proxy.sh new file mode 100755 index 000000000..3bf469438 --- /dev/null +++ b/dev-reverse-proxy.sh @@ -0,0 +1,4 @@ +#!/bin/sh +# Run an nginx reverse proxy with a subpath for development testing +cd "$(dirname "$0")" || exit 1 +docker-compose -f nginx/nginx.yaml up --build diff --git a/dev-server-ttabs.sh b/dev-server-ttabs.sh new file mode 100755 index 000000000..606610d15 --- /dev/null +++ b/dev-server-ttabs.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# Open all three development server processes in macOS terminal tabs +# Requires npm ttab +CODEX_DIR="$(dirname "$0")" + +# The API server +ttab -t "Codex Django" "DEV=1 $CODEX_DIR/run.sh" +# Django livereload server for Django HMR +ttab -t "Codex Django livereload" "$CODEX_DIR/dev-livereload.sh" +# The Vue dev server +ttab -t "Codex Vue" "$CODEX_DIR/dev-frontend.sh" +# An nginx reverse proxy with docker +ttab -t "Codex Nginx" "$CODEX_DIR/dev-reverse-proxy.sh" diff --git a/dev-server.sh b/dev-server.sh deleted file mode 100755 index fee46ebab..000000000 --- a/dev-server.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -# Open all three development server processes in macOS terminal tabs -# requires npm ttab -CODEX_DIR="$(dirname "$0")" -CODEX_VUE_DIR="${CODEX_DIR}/codex_vue" - -# The API server -ttab -t "Codex Django" "cd $CODEX_DIR && DEV=1 ./run-server.sh" -# Django livereload server for Django HMR -ttab -t "Codex Django livereload" "cd $CODEX_DIR && DEV=1 ./pm livereload" -# The Vue dev server -ttab -t "Codex Vue" "cd $CODEX_VUE_DIR && npm run dev" diff --git a/docker-compose-build.yaml b/docker-compose-build.yaml new file mode 100644 index 000000000..f1eed720b --- /dev/null +++ b/docker-compose-build.yaml @@ -0,0 +1,12 @@ +version: "3" + +services: + codex-builder: + build: + context: . + dockerfile: Dockerfile.build + image: codex-builder + container_name: codex-builder + volumes: + - ./dist/:/dist/ + - ./test-results/:/test-results/ diff --git a/docker-compose.yaml b/docker-compose.yaml index 5a5211a2f..9a8c42199 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -5,4 +5,9 @@ services: image: ajslater/codex container_name: codex ports: - - "8000:8000" + - "9810:9810" + volumes: + - ./config:/config + - /Volumes/Media/Comics/:/comics + env_file: + - docker-env diff --git a/docker-env b/docker-env new file mode 100644 index 000000000..0e58b7777 --- /dev/null +++ b/docker-env @@ -0,0 +1,6 @@ +REPO=ajslater/codex +IMAGE=ajslater/codex +BASE_VERSION=latest +PKG_VERSION=v0.5.0 +PUID=501 +PGID=20 diff --git a/docker-run.sh b/docker-run.sh deleted file mode 100755 index 5f8e41d8c..000000000 --- a/docker-run.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -./setup.sh -./run-server.sh diff --git a/docker/nodesource/nodesource.buster.list b/docker/nodesource/nodesource.buster.list new file mode 100644 index 000000000..aba57b9f5 --- /dev/null +++ b/docker/nodesource/nodesource.buster.list @@ -0,0 +1 @@ +deb https://deb.nodesource.com/node_14.x buster main diff --git a/docker/nodesource/nodesource.focal.list b/docker/nodesource/nodesource.focal.list new file mode 100644 index 000000000..40b1e1676 --- /dev/null +++ b/docker/nodesource/nodesource.focal.list @@ -0,0 +1 @@ +deb https://deb.nodesource.com/node_14.x focal main diff --git a/docker/nodesource/nodesource.gpg.key b/docker/nodesource/nodesource.gpg.key new file mode 100644 index 000000000..1dc1d1016 --- /dev/null +++ b/docker/nodesource/nodesource.gpg.key @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 +Comment: GPGTools - https://gpgtools.org + +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 +=CLGF +-----END PGP PUBLIC KEY BLOCK----- diff --git a/fix-lint.sh b/fix-lint.sh new file mode 100755 index 000000000..76636bd29 --- /dev/null +++ b/fix-lint.sh @@ -0,0 +1,5 @@ +#!/bin/sh +# Fix as much as many linting issues as we can +poetry run isort --color . +poetry run black . +prettier --write . diff --git a/fix.sh b/fix.sh deleted file mode 100755 index 6c110c663..000000000 --- a/fix.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -set -euo pipefail -poetry run isort -rc . -poetry run black . -prettier --write . diff --git a/codex_vue/.browserslistrc b/frontend/.browserslistrc similarity index 100% rename from codex_vue/.browserslistrc rename to frontend/.browserslistrc diff --git a/codex_vue/.eslintrc.js b/frontend/.eslintrc.js similarity index 100% rename from codex_vue/.eslintrc.js rename to frontend/.eslintrc.js diff --git a/frontend/.prettierignore b/frontend/.prettierignore new file mode 100644 index 000000000..09a1edf97 --- /dev/null +++ b/frontend/.prettierignore @@ -0,0 +1,4 @@ +public/index.html +dist +node_modules +webpack-stats.json diff --git a/frontend/README.md b/frontend/README.md new file mode 100644 index 000000000..472c980c9 --- /dev/null +++ b/frontend/README.md @@ -0,0 +1,11 @@ +# Codex Frontend + +The codex frontend is built with [VueJS](https://vuejs.org/) and [Vuetify](https://vuetifyjs.com). + +## Development + +See the package.json file for common development scripts. Running the live reloading dev server is your best bet. + +## Production + +After being built, the javascript & css assets are collected by the django collectstatic script and packaged with the main server app. diff --git a/codex_vue/babel.config.js b/frontend/babel.config.js similarity index 100% rename from codex_vue/babel.config.js rename to frontend/babel.config.js diff --git a/frontend/jest.config.js b/frontend/jest.config.js new file mode 100644 index 000000000..6dda9e7a1 --- /dev/null +++ b/frontend/jest.config.js @@ -0,0 +1,3 @@ +module.exports = { + preset: "@vue/cli-plugin-unit-jest", +}; diff --git a/codex_vue/package-lock.json b/frontend/package-lock.json similarity index 63% rename from codex_vue/package-lock.json rename to frontend/package-lock.json index d2bae5cf7..bb8859e0e 100644 --- a/codex_vue/package-lock.json +++ b/frontend/package-lock.json @@ -1,9 +1,48 @@ { - "name": "codex_vue", - "version": "0.1.0", + "name": "codex", + "version": "0.5.0", "lockfileVersion": 1, "requires": true, "dependencies": { + "@ant-design-vue/babel-helper-vue-transform-on": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@ant-design-vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.1.tgz", + "integrity": "sha512-dOAPf/tCM2lCG8FhvOMFBaOdMElMEGhOoocMXEWvHW2l1KIex+UibDcq4bdBEJpDMLrnbNOqci9E7P2dARP6lg==", + "dev": true + }, + "@ant-design-vue/babel-plugin-jsx": { + "version": "1.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@ant-design-vue/babel-plugin-jsx/-/babel-plugin-jsx-1.0.0-rc.1.tgz", + "integrity": "sha512-x7PfAHSs5/emIuey1Df7Bh/vJU27S9KBdufzoAA7kgwTpEpY85R7CXD9gl6sJFB7aG2pZpl4Tmm+FsHlzgp7fA==", + "dev": true, + "requires": { + "@ant-design-vue/babel-helper-vue-transform-on": "^1.0.0", + "@babel/helper-module-imports": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "camelcase": "^6.0.0", + "html-tags": "^3.1.0", + "svg-tags": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "dev": true + } + } + }, + "@arcanis/slice-ansi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@arcanis/slice-ansi/-/slice-ansi-1.0.2.tgz", + "integrity": "sha512-lDL63z0W/L/WTgqrwVOuNyMAsTv+pvjybd21z9SWdStmQoXT59E/iVWwat3gYjcdTNBf6oHAMoyFm8dtjpXEYw==", + "dev": true, + "requires": { + "grapheme-splitter": "^1.0.4" + } + }, "@babel/code-frame": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", @@ -14,38 +53,157 @@ } }, "@babel/compat-data": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.9.6.tgz", - "integrity": "sha512-5QPTrNen2bm7RBc7dsOmcA5hbrS4O2Vhmk5XOL4zWW/zD/hV0iinpefDlkm+tBBy8kDtFaaeEvmAqt+nURAV2g==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.11.0.tgz", + "integrity": "sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ==", "dev": true, "requires": { - "browserslist": "^4.11.1", + "browserslist": "^4.12.0", "invariant": "^2.2.4", "semver": "^5.5.0" } }, "@babel/core": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.6.tgz", - "integrity": "sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helpers": "^7.9.6", - "@babel/parser": "^7.9.6", - "@babel/template": "^7.8.6", - "@babel/traverse": "^7.9.6", - "@babel/types": "^7.9.6", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.5.tgz", + "integrity": "sha512-O34LQooYVDXPl7QWCdW9p4NR+QlzOr7xShPPJz8GsuCU3/8ua/wqTr7gmnxXv+WBESiGU/G5s16i6tUvHkNb+w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.5", + "@babel/helper-module-transforms": "^7.10.5", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.10.5", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.5", + "@babel/types": "^7.10.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", "json5": "^2.1.2", - "lodash": "^4.17.13", + "lodash": "^4.17.19", "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/generator": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.5.tgz", + "integrity": "sha512-3vXxr3FEW7E7lJZiWQ3bM4+v/Vyr9C+hpolQ8BGFr9Y8Ri2tFLWTixmwKBafDujO1WVah4fhZBeU1bieKdghig==", + "dev": true, + "requires": { + "@babel/types": "^7.10.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", + "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.5.tgz", + "integrity": "sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.5.tgz", + "integrity": "sha512-yc/fyv2gUjPqzTz0WHeRJH2pv7jA9kA7mBX2tXl/x5iOE81uaVPuGPtaYk7wmkx4b67mQ7NqI8rmT2pF47KYKQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/parser": "^7.10.5", + "@babel/types": "^7.10.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz", + "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } } }, "@babel/generator": { @@ -61,81 +219,298 @@ } }, "@babel/helper-annotate-as-pure": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz", - "integrity": "sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", + "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz", - "integrity": "sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz", + "integrity": "sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==", "dev": true, "requires": { - "@babel/helper-explode-assignable-expression": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-explode-assignable-expression": "^7.10.4", + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-compilation-targets": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.9.6.tgz", - "integrity": "sha512-x2Nvu0igO0ejXzx09B/1fGBxY9NXQlBW2kZsSxCJft+KHN8t9XWzIvFxtPHnBOAXpVsdxZKZFbRUC8TsNKajMw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz", + "integrity": "sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ==", "dev": true, "requires": { - "@babel/compat-data": "^7.9.6", - "browserslist": "^4.11.1", + "@babel/compat-data": "^7.10.4", + "browserslist": "^4.12.0", "invariant": "^2.2.4", "levenary": "^1.1.1", "semver": "^5.5.0" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.9.6.tgz", - "integrity": "sha512-6N9IeuyHvMBRyjNYOMJHrhwtu4WJMrYf8hVbEHD3pbbbmNOk1kmXSQs7bA4dYDUaIx4ZEzdnvo6NwC3WHd/Qow==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz", + "integrity": "sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-member-expression-to-functions": "^7.8.3", - "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-replace-supers": "^7.9.6", - "@babel/helper-split-export-declaration": "^7.8.3" + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-member-expression-to-functions": "^7.10.5", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz", + "integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz", - "integrity": "sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz", + "integrity": "sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-regex": "^7.8.3", + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-regex": "^7.10.4", "regexpu-core": "^4.7.0" } }, "@babel/helper-define-map": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz", - "integrity": "sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz", + "integrity": "sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.8.3", - "@babel/types": "^7.8.3", - "lodash": "^4.17.13" + "@babel/helper-function-name": "^7.10.4", + "@babel/types": "^7.10.5", + "lodash": "^4.17.19" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz", + "integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-explode-assignable-expression": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz", - "integrity": "sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw==", + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz", + "integrity": "sha512-ux9hm3zR4WV1Y3xXxXkdG/0gxF9nvI0YVmKVhvK9AfMoaQkemL3sJpXw+Xbz65azo8qJiEz2XVDUpK3KYhH3ZQ==", "dev": true, "requires": { - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-function-name": { @@ -159,104 +534,533 @@ } }, "@babel/helper-hoist-variables": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz", - "integrity": "sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz", + "integrity": "sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-member-expression-to-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", - "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.5.tgz", + "integrity": "sha512-HiqJpYD5+WopCXIAbQDG0zye5XYVvcO9w/DHp5GsaGkRUaamLj2bEtu6i8rnGGprAhHM3qidCMgp71HF4endhA==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.5" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/types": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz", + "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } } }, "@babel/helper-module-imports": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", - "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/types": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz", + "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } } }, "@babel/helper-module-transforms": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", - "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.6", - "@babel/helper-simple-access": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/template": "^7.8.6", - "@babel/types": "^7.9.0", - "lodash": "^4.17.13" + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.5.tgz", + "integrity": "sha512-4P+CWMJ6/j1W915ITJaUkadLObmCRRSC234uctJfn/vHrsLNxsR8dwlcXv9ZhJWzl77awf+mWXSZEKt5t0OnlA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.5", + "lodash": "^4.17.19" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", + "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.5.tgz", + "integrity": "sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/types": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz", + "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } } }, "@babel/helper-optimise-call-expression": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", - "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/types": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz", + "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } } }, "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", "dev": true }, "@babel/helper-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.8.3.tgz", - "integrity": "sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.5.tgz", + "integrity": "sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg==", "dev": true, "requires": { - "lodash": "^4.17.13" + "lodash": "^4.17.19" } }, "@babel/helper-remap-async-to-generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz", - "integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==", + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.11.4.tgz", + "integrity": "sha512-tR5vJ/vBa9wFy3m5LLv2faapJLnDFxNWff2SAYkSE4rLUdbp7CdObYFgI7wK4T/Mj4UzpjPwzR8Pzmr5m7MHGA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-wrap-function": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-wrap-function": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz", + "integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-replace-supers": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz", - "integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", + "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.8.3", - "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/traverse": "^7.9.6", - "@babel/types": "^7.9.6" + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/generator": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.5.tgz", + "integrity": "sha512-3vXxr3FEW7E7lJZiWQ3bM4+v/Vyr9C+hpolQ8BGFr9Y8Ri2tFLWTixmwKBafDujO1WVah4fhZBeU1bieKdghig==", + "dev": true, + "requires": { + "@babel/types": "^7.10.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", + "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.5.tgz", + "integrity": "sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.5.tgz", + "integrity": "sha512-yc/fyv2gUjPqzTz0WHeRJH2pv7jA9kA7mBX2tXl/x5iOE81uaVPuGPtaYk7wmkx4b67mQ7NqI8rmT2pF47KYKQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/parser": "^7.10.5", + "@babel/types": "^7.10.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz", + "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } } }, "@babel/helper-simple-access": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", - "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", + "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", "dev": true, "requires": { - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.5.tgz", + "integrity": "sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/types": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz", + "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz", + "integrity": "sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-split-export-declaration": { @@ -275,26 +1079,258 @@ "dev": true }, "@babel/helper-wrap-function": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", - "integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz", + "integrity": "sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-function-name": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/generator": { + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.4.tgz", + "integrity": "sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz", + "integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", + "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.0", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.0", + "@babel/types": "^7.11.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helpers": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz", - "integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", + "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", "dev": true, "requires": { - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.9.6", - "@babel/types": "^7.9.6" + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/generator": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.5.tgz", + "integrity": "sha512-3vXxr3FEW7E7lJZiWQ3bM4+v/Vyr9C+hpolQ8BGFr9Y8Ri2tFLWTixmwKBafDujO1WVah4fhZBeU1bieKdghig==", + "dev": true, + "requires": { + "@babel/types": "^7.10.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", + "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.5.tgz", + "integrity": "sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.5.tgz", + "integrity": "sha512-yc/fyv2gUjPqzTz0WHeRJH2pv7jA9kA7mBX2tXl/x5iOE81uaVPuGPtaYk7wmkx4b67mQ7NqI8rmT2pF47KYKQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/parser": "^7.10.5", + "@babel/types": "^7.10.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz", + "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } } }, "@babel/highlight": { @@ -315,116 +1351,147 @@ "dev": true }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz", - "integrity": "sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz", + "integrity": "sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-remap-async-to-generator": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-remap-async-to-generator": "^7.10.4", "@babel/plugin-syntax-async-generators": "^7.8.0" } }, "@babel/plugin-proposal-class-properties": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz", - "integrity": "sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz", + "integrity": "sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-create-class-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-proposal-decorators": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.8.3.tgz", - "integrity": "sha512-e3RvdvS4qPJVTe288DlXjwKflpfy1hr0j5dz5WpIYYeP7vQZg2WfAEIp8k5/Lwis/m5REXEteIz6rrcDtXXG7w==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.10.5.tgz", + "integrity": "sha512-Sc5TAQSZuLzgY0664mMDn24Vw2P8g/VhyLyGPaWiHahhgLqeZvcGeyBZOrJW0oSKIK2mvQ22a1ENXBIQLhrEiQ==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-decorators": "^7.8.3" + "@babel/helper-create-class-features-plugin": "^7.10.5", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-decorators": "^7.10.4" } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz", - "integrity": "sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz", + "integrity": "sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-dynamic-import": "^7.8.0" } }, + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz", + "integrity": "sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, "@babel/plugin-proposal-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz", - "integrity": "sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz", + "integrity": "sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.0" } }, + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz", + "integrity": "sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz", + "integrity": "sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz", - "integrity": "sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz", + "integrity": "sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.6.tgz", - "integrity": "sha512-Ga6/fhGqA9Hj+y6whNpPv8psyaK5xzrQwSPsGPloVkvmH+PqW1ixdnfJ9uIO06OjQNYol3PMnfmJ8vfZtkzF+A==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz", + "integrity": "sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.9.5" + "@babel/plugin-transform-parameters": "^7.10.4" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz", + "integrity": "sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz", - "integrity": "sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz", + "integrity": "sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0", "@babel/plugin-syntax-optional-chaining": "^7.8.0" } }, + "@babel/plugin-proposal-private-methods": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz", + "integrity": "sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz", - "integrity": "sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz", + "integrity": "sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.8.8", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-async-generators": { @@ -436,13 +1503,22 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-class-properties": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", + "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, "@babel/plugin-syntax-decorators": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.8.3.tgz", - "integrity": "sha512-8Hg4dNNT9/LcA1zQlfwuKR8BUc/if7Q7NkTam9sGTcJphLwpf2g4S42uhspQrIrR+dpzE0dtTqBVFoHl8GtnnQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.10.4.tgz", + "integrity": "sha512-2NaoC6fAk2VMdhY1eerkfHV+lVYC1u8b+jmRJISqANCJlTxYy19HGdIkkQtix2UtkcPuPu+IlDgrVseZnU03bw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-dynamic-import": { @@ -454,6 +1530,15 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, "@babel/plugin-syntax-json-strings": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", @@ -464,12 +1549,21 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.3.tgz", - "integrity": "sha512-WxdW9xyLgBdefoo0Ynn3MRSkhe5tFVxxKNVdnZSh318WrG2e2jH+E9wd/++JsqcLJZPfz87njQJ8j2Upjm0M0A==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.4.tgz", + "integrity": "sha512-KCg9mio9jwiARCB7WAcQ7Y1q+qicILjoK8LP/VkPkEKaf5dkaZZK1EcTe91a3JJlZ3qy6L5s9X52boEYi8DM9g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-nullish-coalescing-operator": { @@ -482,12 +1576,12 @@ } }, "@babel/plugin-syntax-numeric-separator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz", - "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-object-rest-spread": { @@ -518,398 +1612,623 @@ } }, "@babel/plugin-syntax-top-level-await": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz", - "integrity": "sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz", + "integrity": "sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz", - "integrity": "sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz", + "integrity": "sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz", - "integrity": "sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz", + "integrity": "sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-remap-async-to-generator": "^7.8.3" + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-remap-async-to-generator": "^7.10.4" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz", - "integrity": "sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz", + "integrity": "sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz", - "integrity": "sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w==", + "version": "7.11.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz", + "integrity": "sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "lodash": "^4.17.13" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-classes": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.5.tgz", - "integrity": "sha512-x2kZoIuLC//O5iA7PEvecB105o7TLzZo8ofBVhP79N+DO3jaX+KYfww9TQcfBEZD0nikNyYcGB1IKtRq36rdmg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-define-map": "^7.8.3", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.6", - "@babel/helper-split-export-declaration": "^7.8.3", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz", + "integrity": "sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-define-map": "^7.10.4", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", "globals": "^11.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz", + "integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/plugin-transform-computed-properties": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz", - "integrity": "sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz", + "integrity": "sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-destructuring": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.9.5.tgz", - "integrity": "sha512-j3OEsGel8nHL/iusv/mRd5fYZ3DrOxWC82x0ogmdN/vHfAP4MYw+AFKYanzWlktNwikKvlzUV//afBW5FTp17Q==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz", + "integrity": "sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz", - "integrity": "sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz", + "integrity": "sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz", - "integrity": "sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz", + "integrity": "sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz", - "integrity": "sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz", + "integrity": "sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw==", "dev": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-for-of": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz", - "integrity": "sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz", + "integrity": "sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz", - "integrity": "sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz", + "integrity": "sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz", + "integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/plugin-transform-literals": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz", - "integrity": "sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz", + "integrity": "sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz", - "integrity": "sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz", + "integrity": "sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.6.tgz", - "integrity": "sha512-zoT0kgC3EixAyIAU+9vfaUVKTv9IxBDSabgHoUCBP6FqEJ+iNiN7ip7NBKcYqbfUDfuC2mFCbM7vbu4qJgOnDw==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz", + "integrity": "sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-module-transforms": "^7.10.5", + "@babel/helper-plugin-utils": "^7.10.4", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.6.tgz", - "integrity": "sha512-7H25fSlLcn+iYimmsNe3uK1at79IE6SKW9q0/QeEHTMC9MdOZ+4bA+T1VFB5fgOqBWoqlifXRzYD0JPdmIrgSQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz", + "integrity": "sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.6.tgz", - "integrity": "sha512-NW5XQuW3N2tTHim8e1b7qGy7s0kZ2OH3m5octc49K1SdAKGxYxeIx7hiIz05kS1R2R+hOWcsr1eYwcGhrdHsrg==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz", + "integrity": "sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.8.3", - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-hoist-variables": "^7.10.4", + "@babel/helper-module-transforms": "^7.10.5", + "@babel/helper-plugin-utils": "^7.10.4", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz", - "integrity": "sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz", + "integrity": "sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz", - "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz", + "integrity": "sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.8.3" + "@babel/helper-create-regexp-features-plugin": "^7.10.4" } }, "@babel/plugin-transform-new-target": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz", - "integrity": "sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz", + "integrity": "sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-object-super": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz", - "integrity": "sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz", + "integrity": "sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4" } }, "@babel/plugin-transform-parameters": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.5.tgz", - "integrity": "sha512-0+1FhHnMfj6lIIhVvS4KGQJeuhe1GI//h5uptK4PvLt+BGBxsoUJbd3/IW002yk//6sZPlFgsG1hY6OHLcy6kA==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz", + "integrity": "sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + }, + "dependencies": { + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/plugin-transform-property-literals": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz", - "integrity": "sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz", + "integrity": "sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-regenerator": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz", - "integrity": "sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz", + "integrity": "sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw==", "dev": true, "requires": { "regenerator-transform": "^0.14.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz", - "integrity": "sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz", + "integrity": "sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-runtime": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.6.tgz", - "integrity": "sha512-qcmiECD0mYOjOIt8YHNsAP1SxPooC/rDmfmiSK9BNY72EitdSc7l44WTEklaWuFtbOEBjNhWWyph/kOImbNJ4w==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.11.0.tgz", + "integrity": "sha512-LFEsP+t3wkYBlis8w6/kmnd6Kb1dxTd+wGJ8MlxTGzQo//ehtqlVL4S9DNUa53+dtPSQobN2CXx4d81FqC58cw==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", "resolve": "^1.8.1", "semver": "^5.5.1" } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz", - "integrity": "sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz", + "integrity": "sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz", - "integrity": "sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz", + "integrity": "sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz", - "integrity": "sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz", + "integrity": "sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-regex": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-regex": "^7.10.4" } }, "@babel/plugin-transform-template-literals": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz", - "integrity": "sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz", + "integrity": "sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz", - "integrity": "sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz", + "integrity": "sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz", - "integrity": "sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw==", + "@babel/plugin-transform-unicode-escapes": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz", + "integrity": "sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, - "@babel/preset-env": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.6.tgz", - "integrity": "sha512-0gQJ9RTzO0heXOhzftog+a/WyOuqMrAIugVYxMYf83gh1CQaQDjMtsOpqOwXyDL/5JcWsrCm8l4ju8QC97O7EQ==", + "@babel/plugin-transform-unicode-regex": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz", + "integrity": "sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A==", "dev": true, "requires": { - "@babel/compat-data": "^7.9.6", - "@babel/helper-compilation-targets": "^7.9.6", - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-proposal-async-generator-functions": "^7.8.3", - "@babel/plugin-proposal-dynamic-import": "^7.8.3", - "@babel/plugin-proposal-json-strings": "^7.8.3", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-proposal-numeric-separator": "^7.8.3", - "@babel/plugin-proposal-object-rest-spread": "^7.9.6", - "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", - "@babel/plugin-proposal-optional-chaining": "^7.9.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.8.3", + "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/preset-env": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.11.0.tgz", + "integrity": "sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.11.0", + "@babel/helper-compilation-targets": "^7.10.4", + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-proposal-async-generator-functions": "^7.10.4", + "@babel/plugin-proposal-class-properties": "^7.10.4", + "@babel/plugin-proposal-dynamic-import": "^7.10.4", + "@babel/plugin-proposal-export-namespace-from": "^7.10.4", + "@babel/plugin-proposal-json-strings": "^7.10.4", + "@babel/plugin-proposal-logical-assignment-operators": "^7.11.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4", + "@babel/plugin-proposal-numeric-separator": "^7.10.4", + "@babel/plugin-proposal-object-rest-spread": "^7.11.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.10.4", + "@babel/plugin-proposal-optional-chaining": "^7.11.0", + "@babel/plugin-proposal-private-methods": "^7.10.4", + "@babel/plugin-proposal-unicode-property-regex": "^7.10.4", "@babel/plugin-syntax-async-generators": "^7.8.0", + "@babel/plugin-syntax-class-properties": "^7.10.4", "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", - "@babel/plugin-syntax-numeric-separator": "^7.8.0", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.0", "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.8.3", - "@babel/plugin-transform-arrow-functions": "^7.8.3", - "@babel/plugin-transform-async-to-generator": "^7.8.3", - "@babel/plugin-transform-block-scoped-functions": "^7.8.3", - "@babel/plugin-transform-block-scoping": "^7.8.3", - "@babel/plugin-transform-classes": "^7.9.5", - "@babel/plugin-transform-computed-properties": "^7.8.3", - "@babel/plugin-transform-destructuring": "^7.9.5", - "@babel/plugin-transform-dotall-regex": "^7.8.3", - "@babel/plugin-transform-duplicate-keys": "^7.8.3", - "@babel/plugin-transform-exponentiation-operator": "^7.8.3", - "@babel/plugin-transform-for-of": "^7.9.0", - "@babel/plugin-transform-function-name": "^7.8.3", - "@babel/plugin-transform-literals": "^7.8.3", - "@babel/plugin-transform-member-expression-literals": "^7.8.3", - "@babel/plugin-transform-modules-amd": "^7.9.6", - "@babel/plugin-transform-modules-commonjs": "^7.9.6", - "@babel/plugin-transform-modules-systemjs": "^7.9.6", - "@babel/plugin-transform-modules-umd": "^7.9.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", - "@babel/plugin-transform-new-target": "^7.8.3", - "@babel/plugin-transform-object-super": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.9.5", - "@babel/plugin-transform-property-literals": "^7.8.3", - "@babel/plugin-transform-regenerator": "^7.8.7", - "@babel/plugin-transform-reserved-words": "^7.8.3", - "@babel/plugin-transform-shorthand-properties": "^7.8.3", - "@babel/plugin-transform-spread": "^7.8.3", - "@babel/plugin-transform-sticky-regex": "^7.8.3", - "@babel/plugin-transform-template-literals": "^7.8.3", - "@babel/plugin-transform-typeof-symbol": "^7.8.4", - "@babel/plugin-transform-unicode-regex": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.10.4", + "@babel/plugin-transform-arrow-functions": "^7.10.4", + "@babel/plugin-transform-async-to-generator": "^7.10.4", + "@babel/plugin-transform-block-scoped-functions": "^7.10.4", + "@babel/plugin-transform-block-scoping": "^7.10.4", + "@babel/plugin-transform-classes": "^7.10.4", + "@babel/plugin-transform-computed-properties": "^7.10.4", + "@babel/plugin-transform-destructuring": "^7.10.4", + "@babel/plugin-transform-dotall-regex": "^7.10.4", + "@babel/plugin-transform-duplicate-keys": "^7.10.4", + "@babel/plugin-transform-exponentiation-operator": "^7.10.4", + "@babel/plugin-transform-for-of": "^7.10.4", + "@babel/plugin-transform-function-name": "^7.10.4", + "@babel/plugin-transform-literals": "^7.10.4", + "@babel/plugin-transform-member-expression-literals": "^7.10.4", + "@babel/plugin-transform-modules-amd": "^7.10.4", + "@babel/plugin-transform-modules-commonjs": "^7.10.4", + "@babel/plugin-transform-modules-systemjs": "^7.10.4", + "@babel/plugin-transform-modules-umd": "^7.10.4", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.10.4", + "@babel/plugin-transform-new-target": "^7.10.4", + "@babel/plugin-transform-object-super": "^7.10.4", + "@babel/plugin-transform-parameters": "^7.10.4", + "@babel/plugin-transform-property-literals": "^7.10.4", + "@babel/plugin-transform-regenerator": "^7.10.4", + "@babel/plugin-transform-reserved-words": "^7.10.4", + "@babel/plugin-transform-shorthand-properties": "^7.10.4", + "@babel/plugin-transform-spread": "^7.11.0", + "@babel/plugin-transform-sticky-regex": "^7.10.4", + "@babel/plugin-transform-template-literals": "^7.10.4", + "@babel/plugin-transform-typeof-symbol": "^7.10.4", + "@babel/plugin-transform-unicode-escapes": "^7.10.4", + "@babel/plugin-transform-unicode-regex": "^7.10.4", "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.9.6", - "browserslist": "^4.11.1", + "@babel/types": "^7.11.0", + "browserslist": "^4.12.0", "core-js-compat": "^3.6.2", "invariant": "^2.2.2", "levenary": "^1.1.1", "semver": "^5.5.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/preset-modules": { @@ -973,6 +2292,16 @@ "to-fast-properties": "^2.0.0" } }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, "@hapi/address": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", @@ -1023,16 +2352,261 @@ "postcss": "^7.0.0" } }, + "@jest/console": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", + "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==", + "dev": true, + "requires": { + "@jest/source-map": "^24.9.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + } + }, + "@jest/core": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.9.0.tgz", + "integrity": "sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/reporters": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "graceful-fs": "^4.1.15", + "jest-changed-files": "^24.9.0", + "jest-config": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-resolve-dependencies": "^24.9.0", + "jest-runner": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "jest-watcher": "^24.9.0", + "micromatch": "^3.1.10", + "p-each-series": "^1.0.0", + "realpath-native": "^1.1.0", + "rimraf": "^2.5.4", + "slash": "^2.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "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 + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "@jest/environment": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.9.0.tgz", + "integrity": "sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==", + "dev": true, + "requires": { + "@jest/fake-timers": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0" + } + }, + "@jest/fake-timers": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz", + "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-mock": "^24.9.0" + } + }, + "@jest/reporters": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz", + "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.2", + "istanbul-lib-coverage": "^2.0.2", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.1", + "istanbul-reports": "^2.2.6", + "jest-haste-map": "^24.9.0", + "jest-resolve": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.6.0", + "node-notifier": "^5.4.2", + "slash": "^2.0.0", + "source-map": "^0.6.0", + "string-length": "^2.0.0" + }, + "dependencies": { + "jest-worker": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", + "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^6.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 + }, + "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" + } + } + } + }, + "@jest/source-map": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", + "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.1.15", + "source-map": "^0.6.0" + }, + "dependencies": { + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "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 + } + } + }, + "@jest/test-result": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", + "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", + "dev": true, + "requires": { + "@jest/console": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/istanbul-lib-coverage": "^2.0.0" + } + }, + "@jest/test-sequencer": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", + "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", + "dev": true, + "requires": { + "@jest/test-result": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-runner": "^24.9.0", + "jest-runtime": "^24.9.0" + } + }, + "@jest/transform": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz", + "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.9.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.15", + "jest-haste-map": "^24.9.0", + "jest-regex-util": "^24.9.0", + "jest-util": "^24.9.0", + "micromatch": "^3.1.10", + "pirates": "^4.0.1", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.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 + }, + "write-file-atomic": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz", + "integrity": "sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + } + } + }, + "@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + } + }, "@mdi/font": { - "version": "5.3.45", - "resolved": "https://registry.npmjs.org/@mdi/font/-/font-5.3.45.tgz", - "integrity": "sha512-SD5d2vHEKRvDCInZQFXOwiFpBlzpuZOiqwxKf6E+zCt7UDc52TUSrL0+TXqY57VQh/SnTpZVXM+Uvs21OdPFWg==", + "version": "5.5.55", + "resolved": "https://registry.npmjs.org/@mdi/font/-/font-5.5.55.tgz", + "integrity": "sha512-xrVCXiRMz7ubB8mu6ehDhMADmGpLBsk3GWZccs39jWmhoTxatFnOvW8STJjqMGtePPNgGYYu/6m/AJVyMjBxnw==", "dev": true }, "@mdi/js": { - "version": "5.3.45", - "resolved": "https://registry.npmjs.org/@mdi/js/-/js-5.3.45.tgz", - "integrity": "sha512-r05JoeUhokSERwW6yYi3WcKCBePHHqBvIikOD0X/dWyaZb6gIRth5Lya7VVTItvGo1qlpp8LpMJKmE6o49+G+Q==", + "version": "5.5.55", + "resolved": "https://registry.npmjs.org/@mdi/js/-/js-5.5.55.tgz", + "integrity": "sha512-vbw1QW3M9A4vObU9WmTETTG7n7feC9HSn/3up8ZYk/M3K9fGL9FPtw0+bdASRu1UOBgEsqC9eBhNW10IOcwMIg==", "dev": true }, "@mrmlnc/readdir-enhanced": { @@ -1080,15 +2654,15 @@ } }, "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-3.1.2.tgz", + "integrity": "sha512-JiX9vxoKMmu8Y3Zr2RVathBL1Cdu4Nt4MuNWemt1Nc06A0RAin9c5FArkhGsyMBWfCu4zj+9b+GxtjAnE4qqLQ==", "dev": true }, "@snyk/cli-interface": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.8.0.tgz", - "integrity": "sha512-St/G39iJG1zQK15L24kcVYM2gmFc/ylBCcBqU2DMZKJKwOPccKLUO6s+dWIUXMccQ+DFS6TuHPvuAKQNi9C4Yg==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.8.1.tgz", + "integrity": "sha512-pALcfgoY0hAavy/pBlDIqEu+FFC5m+D4bMnCwlQ26mObL/zzxp2+Ohx+HykCIom62u2J94SzAtRLFdm/2TgoOw==", "dev": true, "requires": { "@snyk/dep-graph": "1.19.0", @@ -1111,9 +2685,9 @@ }, "dependencies": { "tslib": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", - "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz", + "integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==", "dev": true } } @@ -1133,44 +2707,38 @@ } }, "@snyk/cocoapods-lockfile-parser": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@snyk/cocoapods-lockfile-parser/-/cocoapods-lockfile-parser-3.4.0.tgz", - "integrity": "sha512-mAWgKIHFv0QEGpRvocVMxLAdJx7BmXtVOyQN/VtsGBoGFKqhO0jbtKUUVJC4b0jyKfVmEF2puo94i+1Uqz5q6A==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@snyk/cocoapods-lockfile-parser/-/cocoapods-lockfile-parser-3.5.1.tgz", + "integrity": "sha512-0bzajH/HdP3k5cOZKUmT/xqmHZFuWN124c/lrqh+U6Q1Z9Bt7TLOB2ifLKL+1I4rq+IgOesGWJYG1KhxBy3RLw==", "dev": true, "requires": { - "@snyk/dep-graph": "1.18.4", - "@snyk/ruby-semver": "^2.0.4", + "@snyk/dep-graph": "1.19.3", + "@snyk/ruby-semver": "^3.0.0", "@types/js-yaml": "^3.12.1", "js-yaml": "^3.13.1", "source-map-support": "^0.5.7", "tslib": "^1.10.0" }, "dependencies": { - "@snyk/dep-graph": { - "version": "1.18.4", - "resolved": "https://registry.npmjs.org/@snyk/dep-graph/-/dep-graph-1.18.4.tgz", - "integrity": "sha512-SePWsDyD7qrLxFifIieEl4GqyOODfOnP0hmUweTG5YcMroAV5nARGAUcjxREGzbXMcUpPfZhAaqFjYgzUDH8dQ==", + "@snyk/ruby-semver": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@snyk/ruby-semver/-/ruby-semver-3.0.0.tgz", + "integrity": "sha512-GoSRcwNuJ/mK3Q+tqelRJlylPh8K3RZRWh3ZpkOKm1gQPdG+z0wt+LipSIHxGR8yBDl5bQjwTrPLkL49/N1V6Q==", "dev": true, "requires": { - "@snyk/graphlib": "2.1.9-patch", - "@snyk/lodash": "4.17.15-patch", - "object-hash": "^2.0.3", - "semver": "^7.3.2", - "source-map-support": "^0.5.19", - "tslib": "^1.11.1" + "lodash.escaperegexp": "^4.1.0", + "lodash.flatten": "^4.4.0", + "lodash.uniq": "^4.5.0", + "tslib": "^1.13.0" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } } - }, - "object-hash": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.0.3.tgz", - "integrity": "sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg==", - "dev": true - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true } } }, @@ -1184,19 +2752,43 @@ } }, "@snyk/dep-graph": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/@snyk/dep-graph/-/dep-graph-1.18.3.tgz", - "integrity": "sha512-7qWRTIJdZuc5VzDjdV2+03AHElyAZmhq7eV9BRu+jqrYjo9ohWBGEZgYslrTdvfqfJ8rkdrG3j0/0Aa25IxJcg==", + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/@snyk/dep-graph/-/dep-graph-1.19.3.tgz", + "integrity": "sha512-WJLUFKBokoFK5imi0t8Dkyj+uqtS/5Ziuf4oE/OOFX30UqP1ffMDkv9/3sqBJQVQ9FjdgsX3Cm8JZMtMlYRc6w==", "dev": true, "requires": { - "@snyk/graphlib": "2.1.9-patch", - "@snyk/lodash": "4.17.15-patch", + "@snyk/graphlib": "2.1.9-patch.2", + "lodash.isequal": "^4.5.0", "object-hash": "^2.0.3", - "semver": "^7.3.2", + "semver": "^6.0.0", "source-map-support": "^0.5.19", - "tslib": "^1.11.1" + "tslib": "^1.13.0" }, "dependencies": { + "@snyk/graphlib": { + "version": "2.1.9-patch.2", + "resolved": "https://registry.npmjs.org/@snyk/graphlib/-/graphlib-2.1.9-patch.2.tgz", + "integrity": "sha512-BjJzOXDNzoEMBOjSks7vadu5f0c39SeorJMi9vUvvWM5dcE22CZqcN9VMRW5DYTifUJiCWszkm5TOyfYfB0bfg==", + "dev": true, + "requires": { + "lodash.clone": "^4.5.0", + "lodash.constant": "^3.0.0", + "lodash.filter": "^4.6.0", + "lodash.foreach": "^4.5.0", + "lodash.has": "^4.5.2", + "lodash.isarray": "^4.0.0", + "lodash.isempty": "^4.4.0", + "lodash.isfunction": "^3.0.9", + "lodash.isundefined": "^3.0.1", + "lodash.keys": "^4.2.0", + "lodash.map": "^4.6.0", + "lodash.reduce": "^4.6.0", + "lodash.size": "^4.2.0", + "lodash.transform": "^4.6.0", + "lodash.union": "^4.6.0", + "lodash.values": "^4.3.0" + } + }, "object-hash": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.0.3.tgz", @@ -1204,13 +2796,30 @@ "dev": true }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", "dev": true } } }, + "@snyk/docker-registry-v2-client": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@snyk/docker-registry-v2-client/-/docker-registry-v2-client-1.13.5.tgz", + "integrity": "sha512-lgJiC071abCpFVLp47OnykU8MMrhdQe386Wt6QaDmjI0s2DQn/S58NfdLrPU7s6l4zoGT7UwRW9+7paozRgFTA==", + "dev": true, + "requires": { + "needle": "^2.5.0", + "parse-link-header": "^1.0.1", + "tslib": "^1.10.0" + } + }, "@snyk/gemfile": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@snyk/gemfile/-/gemfile-1.2.0.tgz", @@ -1321,9 +2930,9 @@ } }, "@snyk/java-call-graph-builder": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@snyk/java-call-graph-builder/-/java-call-graph-builder-1.10.0.tgz", - "integrity": "sha512-x3vKElHJRsPjlMBRACeD6kHtki54ffahYeAm4ny5epVpxm16/OT6f6AjNjPuX8DbxcauaD7wqirtc62OPH3YqA==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/@snyk/java-call-graph-builder/-/java-call-graph-builder-1.13.1.tgz", + "integrity": "sha512-oOCSIyOMplV73a1agcXKXlFYQftK5esUUaFRTf90GOxQwKy8R9tZtKdP+CdutlgvjRP286DQ+7GlvKYsGGZbWg==", "dev": true, "requires": { "@snyk/graphlib": "2.1.9-patch", @@ -1360,17 +2969,6 @@ "dev": true, "requires": { "event-loop-spinner": "^2.0.0" - }, - "dependencies": { - "event-loop-spinner": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/event-loop-spinner/-/event-loop-spinner-2.0.0.tgz", - "integrity": "sha512-1y4j/Mhttr8ordvHkbDsGzGrlQaSYJoXD/3YKUxiOXIk7myEn9UPfybEk/lLtrcU3D4QvCNmVUxVQaPtvAIaUw==", - "dev": true, - "requires": { - "tslib": "^1.10.0" - } - } } }, "@snyk/ruby-semver": { @@ -1383,24 +2981,25 @@ } }, "@snyk/snyk-cocoapods-plugin": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@snyk/snyk-cocoapods-plugin/-/snyk-cocoapods-plugin-2.3.0.tgz", - "integrity": "sha512-4V1xJMqsK6J3jHu9UufKySorzA8O1vNLRIK1JgJf5KcXQCP44SJI5dk9Xr9iFGXXtGo8iI9gmokQcHlGpkPSJg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@snyk/snyk-cocoapods-plugin/-/snyk-cocoapods-plugin-2.5.0.tgz", + "integrity": "sha512-arK4VHzNh/D9vCFQFeAiSP+rMRXwLbzaRoIKucodf8Q/3KftIo/byeDmoc2Cc7awR1HPo5E391bwBNH5ra8UqA==", "dev": true, "requires": { - "@snyk/cli-interface": "1.5.0", - "@snyk/cocoapods-lockfile-parser": "3.4.0", - "@snyk/dep-graph": "^1.18.2", + "@snyk/cli-interface": "2.6.1", + "@snyk/cocoapods-lockfile-parser": "3.5.1", + "@snyk/dep-graph": "^1.19.0", "source-map-support": "^0.5.7", "tslib": "^2.0.0" }, "dependencies": { "@snyk/cli-interface": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-1.5.0.tgz", - "integrity": "sha512-+Qo+IO3YOXWgazlo+CKxOuWFLQQdaNCJ9cSfhFQd687/FuesaIxWdInaAdfpsLScq0c6M1ieZslXgiZELSzxbg==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.6.1.tgz", + "integrity": "sha512-3X+OwwwT9j0r2ObqxYIiAgdaHsTW71b92PN3wawGAxl4YgPRrRVw8Fouhe41I4WJsn7OlKUNedylZguvpYg9qw==", "dev": true, "requires": { + "@snyk/graphlib": "2.1.9-patch", "tslib": "^1.9.3" }, "dependencies": { @@ -1413,13 +3012,36 @@ } }, "tslib": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", - "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz", + "integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==", "dev": true } } }, + "@snyk/snyk-docker-pull": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@snyk/snyk-docker-pull/-/snyk-docker-pull-3.2.0.tgz", + "integrity": "sha512-uWKtjh29I/d0mfmfBN7w6RwwNBQxQVKrauF5ND/gqb0PVsKV22GIpkI+viWjI7KNKso6/B0tMmsv7TX2tsNcLQ==", + "dev": true, + "requires": { + "@snyk/docker-registry-v2-client": "^1.13.5", + "child-process": "^1.0.2", + "tar-stream": "^2.1.2", + "tmp": "^0.1.0" + }, + "dependencies": { + "tmp": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", + "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", + "dev": true, + "requires": { + "rimraf": "^2.6.3" + } + } + } + }, "@soda/friendly-errors-webpack-plugin": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.7.1.tgz", @@ -1507,18 +3129,87 @@ } }, "@soda/get-current-script": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@soda/get-current-script/-/get-current-script-1.0.0.tgz", - "integrity": "sha512-9GvTek+7cVw7r+L7TNGOG1astZJWXz2h5q4BqMXl28KN+24iSCm1xo+RhZOZvwdT3bzNe9hD7riJc/lBoO7mgg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@soda/get-current-script/-/get-current-script-1.0.2.tgz", + "integrity": "sha512-T7VNNlYVM1SgQ+VsMYhnDkcGmWhQdL0bDyGm5TlQ3GBXnJscEClUUOKduWTmm2zCnvNLC1hc3JpuXjs/nFOc5w==", "dev": true }, "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz", + "integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==", + "dev": true, + "requires": { + "defer-to-connect": "^2.0.0" + } + }, + "@types/anymatch": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", + "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", + "dev": true + }, + "@types/babel__core": { + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", + "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", + "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.13.tgz", + "integrity": "sha512-i+zS7t6/s9cdQvbqKDARrcbrPvtJGlbYsMkazo03nTAK3RX9FNrLllXys22uiTGJapPOTZTQ35nHh4ISph4SLQ==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/cacheable-request": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz", + "integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==", "dev": true, "requires": { - "defer-to-connect": "^1.0.1" + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@types/responselike": "*" } }, "@types/color-name": { @@ -1527,18 +3218,66 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/connect": { + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz", + "integrity": "sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect-history-api-fallback": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.3.tgz", + "integrity": "sha512-7SxFCd+FLlxCfwVwbyPxbR4khL9aNikJhrorw8nUIOqeuooc9gifBuDQOJw5kzN7i6i3vLn9G8Wde/4QDihpYw==", + "dev": true, + "requires": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, "@types/debug": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz", "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==", "dev": true }, + "@types/emscripten": { + "version": "1.39.4", + "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.39.4.tgz", + "integrity": "sha512-k3LLVMFrdNA9UCvMDPWMbFrGPNb+GcPyw29ktJTo1RCN7RmxFG5XzPZcPKRlnLuLT/FRm8wp4ohvDwNY7GlROQ==", + "dev": true + }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", "dev": true }, + "@types/express": { + "version": "4.17.7", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.7.tgz", + "integrity": "sha512-dCOT5lcmV/uC2J9k0rPafATeeyz+99xTt54ReX11/LObZgfzJqZNcW27zGhYyX+9iSEGXGt5qLPwRSvBZcLvtQ==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "*", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.9", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.9.tgz", + "integrity": "sha512-DG0BYg6yO+ePW+XoDENYz8zhNGC3jDDEpComMYn7WJc4mY1Us8Rw9ax2YhJXxpyk2SF47PQAoQ0YyVT1a0bEkA==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, "@types/glob": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", @@ -1556,18 +3295,115 @@ "integrity": "sha512-OW/D8GqCyQtH8F7xDdDxzPJTBgknZeZhlCakUcBCya2rYPRN53F+0YJVwSPyiyAhrknnjkl3P9qVk0oBI4S1qw==", "dev": true }, + "@types/http-cache-semantics": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz", + "integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==", + "dev": true + }, + "@types/http-proxy": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.4.tgz", + "integrity": "sha512-IrSHl2u6AWXduUaDLqYpt45tLVCtYv7o4Z0s1KghBCDgIIS9oW5K1H8mZG/A2CfeLdEa7rTd1ACOiHBc1EMT2Q==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/http-proxy-middleware": { + "version": "0.19.3", + "resolved": "https://registry.npmjs.org/@types/http-proxy-middleware/-/http-proxy-middleware-0.19.3.tgz", + "integrity": "sha512-lnBTx6HCOUeIJMLbI/LaL5EmdKLhczJY5oeXZpX/cXE4rRqb3RmV7VcMpiEfYkmTjipv3h7IAyIINe4plEv7cA==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/http-proxy": "*", + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "24.9.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.9.1.tgz", + "integrity": "sha512-Fb38HkXSVA4L8fGKEZ6le5bB8r6MRWlOCZbVuWZcmOMSCd2wCYOwN1ibj8daIoV9naq7aaOZjrLCoCMptKU/4Q==", + "dev": true, + "requires": { + "jest-diff": "^24.3.0" + } + }, "@types/js-yaml": { "version": "3.12.5", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.5.tgz", "integrity": "sha512-JCcp6J0GV66Y4ZMDAQCXot4xprYB+Zfd3meK9+INSJeVZwJmHAW30BBEEkPzXswMXuiyReUGOP3GxrADc9wPww==", "dev": true }, + "@types/json-schema": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", + "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", + "dev": true + }, + "@types/keyv": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz", + "integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/mime": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz", + "integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q==", + "dev": true + }, + "@types/mini-css-extract-plugin": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@types/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.1.tgz", + "integrity": "sha512-+mN04Oszdz9tGjUP/c1ReVwJXxSniLd7lF++sv+8dkABxVNthg6uccei+4ssKxRHGoMmPxdn7uBdJWONSJGTGQ==", + "dev": true, + "optional": true, + "requires": { + "@types/webpack": "*" + } + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", "dev": true }, + "@types/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", + "dev": true + }, "@types/node": { "version": "13.13.4", "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.4.tgz", @@ -1587,66 +3423,445 @@ "dev": true }, "@types/q": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz", - "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", + "dev": true + }, + "@types/qs": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-+wYo+L6ZF6BMoEjtf8zB2esQsqdV6WsjRK/GP9WOgLPrq87PbNWgIxS76dS5uvl/QXtHGakZmwTznIfcPXcKlQ==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", "dev": true }, + "@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@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/xml2js": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.5.tgz", - "integrity": "sha512-yohU3zMn0fkhlape1nxXG2bLEGZRc1FeqF80RoHaYXJN7uibaauXfhzhOJr1Xh36sn+/tx21QAOf07b/xYVk1w==", + "@types/serve-static": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.5.tgz", + "integrity": "sha512-6M64P58N+OXjU432WoLLBQxbA0LRGBCRm7aAGQJ+SMC1IMl0dgRVi9EFfoDcS2a7Xogygk/eGN94CfwU9UF7UQ==", "dev": true, "requires": { - "@types/node": "*" + "@types/express-serve-static-core": "*", + "@types/mime": "*" } }, - "@vue/babel-helper-vue-jsx-merge-props": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz", - "integrity": "sha512-6tyf5Cqm4m6v7buITuwS+jHzPlIPxbFzEhXR5JGZpbrvOcp1hiQKckd305/3C7C36wFekNTQSxAtgeM0j0yoUw==", + "@types/source-list-map": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", + "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", "dev": true }, - "@vue/babel-plugin-transform-vue-jsx": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.1.2.tgz", - "integrity": "sha512-YfdaoSMvD1nj7+DsrwfTvTnhDXI7bsuh+Y5qWwvQXlD24uLgnsoww3qbiZvWf/EoviZMrvqkqN4CBw0W3BWUTQ==", + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "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/tapable": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.6.tgz", + "integrity": "sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA==", + "dev": true + }, + "@types/uglify-js": { + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.3.tgz", + "integrity": "sha512-KswB5C7Kwduwjj04Ykz+AjvPcfgv/37Za24O2EDzYNbwyzOo8+ydtvzUfZ5UMguiVu29Gx44l1A6VsPPcmYu9w==", "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", - "html-tags": "^2.0.0", - "lodash.kebabcase": "^4.1.1", - "svg-tags": "^1.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 + } } }, - "@vue/babel-preset-app": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-4.3.1.tgz", - "integrity": "sha512-iNkySkbRWXGUA+Cvzj+/gEP0Y0uVAwwzfn21S7hkggSeIg9LJyZ+QzdxgKO0wgi01yTdb2mYWgeLQAfHZ65aew==", + "@types/webpack": { + "version": "4.41.21", + "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.21.tgz", + "integrity": "sha512-2j9WVnNrr/8PLAB5csW44xzQSJwS26aOnICsP3pSGCEdsu6KYtfQ6QJsVUKHWRnm1bL7HziJsfh5fHqth87yKA==", "dev": true, "requires": { - "@babel/core": "^7.9.0", - "@babel/helper-compilation-targets": "^7.8.7", - "@babel/helper-module-imports": "^7.8.3", - "@babel/plugin-proposal-class-properties": "^7.8.3", - "@babel/plugin-proposal-decorators": "^7.8.3", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-jsx": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.9.0", - "@babel/preset-env": "^7.9.0", - "@babel/runtime": "^7.9.2", - "@vue/babel-preset-jsx": "^1.1.2", - "babel-plugin-dynamic-import-node": "^2.3.0", - "core-js": "^3.6.4", - "core-js-compat": "^3.6.4" + "@types/anymatch": "*", + "@types/node": "*", + "@types/tapable": "*", + "@types/uglify-js": "*", + "@types/webpack-sources": "*", + "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 + } + } + }, + "@types/webpack-dev-server": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@types/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", + "integrity": "sha512-3+86AgSzl18n5P1iUP9/lz3G3GMztCp+wxdDvVuNhx1sr1jE79GpYfKHL8k+Vht3N74K2n98CuAEw4YPJCYtDA==", + "dev": true, + "requires": { + "@types/connect-history-api-fallback": "*", + "@types/express": "*", + "@types/http-proxy-middleware": "*", + "@types/serve-static": "*", + "@types/webpack": "*" + } + }, + "@types/webpack-sources": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-1.4.2.tgz", + "integrity": "sha512-77T++JyKow4BQB/m9O96n9d/UUHWLQHlcqXb9Vsf4F1+wKNrrlWNFPDLKNT92RJnCSL6CieTc+NDXtCVZswdTw==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/source-list-map": "*", + "source-map": "^0.7.3" + }, + "dependencies": { + "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 + } + } + }, + "@types/xml2js": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.5.tgz", + "integrity": "sha512-yohU3zMn0fkhlape1nxXG2bLEGZRc1FeqF80RoHaYXJN7uibaauXfhzhOJr1Xh36sn+/tx21QAOf07b/xYVk1w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/yargs": { + "version": "13.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.10.tgz", + "integrity": "sha512-MU10TSgzNABgdzKvQVW1nuuT+sgBMWeXNc3XOs5YXV5SDAK+PPja2eUuBNB9iqElu03xyEDqlnGw0jgl4nbqGQ==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, + "@typescript-eslint/experimental-utils": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", + "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + } + } + }, + "@typescript-eslint/typescript-estree": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", + "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "@vue/babel-helper-vue-jsx-merge-props": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz", + "integrity": "sha512-6tyf5Cqm4m6v7buITuwS+jHzPlIPxbFzEhXR5JGZpbrvOcp1hiQKckd305/3C7C36wFekNTQSxAtgeM0j0yoUw==", + "dev": true + }, + "@vue/babel-plugin-transform-vue-jsx": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.1.2.tgz", + "integrity": "sha512-YfdaoSMvD1nj7+DsrwfTvTnhDXI7bsuh+Y5qWwvQXlD24uLgnsoww3qbiZvWf/EoviZMrvqkqN4CBw0W3BWUTQ==", + "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", + "html-tags": "^2.0.0", + "lodash.kebabcase": "^4.1.1", + "svg-tags": "^1.0.0" + }, + "dependencies": { + "html-tags": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", + "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=", + "dev": true + } + } + }, + "@vue/babel-preset-app": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-4.5.4.tgz", + "integrity": "sha512-a+2s/lL3fE3h9/ekvpMVLhZTDjR3xt+jnpTwuQtEZ3KIuzFHxbmwAjueRZh6BKEGfB6kgZ3KqZHFX3vx/DRJ4w==", + "dev": true, + "requires": { + "@ant-design-vue/babel-plugin-jsx": "^1.0.0-0", + "@babel/core": "^7.11.0", + "@babel/helper-compilation-targets": "^7.9.6", + "@babel/helper-module-imports": "^7.8.3", + "@babel/plugin-proposal-class-properties": "^7.8.3", + "@babel/plugin-proposal-decorators": "^7.8.3", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.11.0", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.0", + "@vue/babel-preset-jsx": "^1.1.2", + "babel-plugin-dynamic-import-node": "^2.3.3", + "core-js": "^3.6.5", + "core-js-compat": "^3.6.5", + "semver": "^6.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/core": { + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.4.tgz", + "integrity": "sha512-5deljj5HlqRXN+5oJTY7Zs37iH3z3b++KjiKtIsJy1NrjOOVSEaJHEetLBhyu0aQOSNNZ/0IuEAan9GzRuDXHg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.4", + "@babel/helper-module-transforms": "^7.11.0", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.11.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.11.0", + "@babel/types": "^7.11.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.4.tgz", + "integrity": "sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", + "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/template": "^7.10.4", + "@babel/types": "^7.11.0", + "lodash": "^4.17.19" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz", + "integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==", + "dev": true + }, + "@babel/runtime": { + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz", + "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", + "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.0", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.0", + "@babel/types": "^7.11.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "@vue/babel-preset-jsx": { @@ -1693,6 +3908,14 @@ "camelcase": "^5.0.0", "html-tags": "^2.0.0", "svg-tags": "^1.0.0" + }, + "dependencies": { + "html-tags": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", + "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=", + "dev": true + } } }, "@vue/babel-sugar-v-on": { @@ -1707,33 +3930,185 @@ } }, "@vue/cli-overlay": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@vue/cli-overlay/-/cli-overlay-4.3.1.tgz", - "integrity": "sha512-UA399aWHhre2VHrQFQSJhFLrFMqOYQ8ly+Ni6T+cpCjOwssjiaqaqrG5YiZBAqDwQvjrtYori4lU66qrY5DVhA==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@vue/cli-overlay/-/cli-overlay-4.5.4.tgz", + "integrity": "sha512-nthli1n7rXaqaMZsH0KNdFqeYJxDOQNeaobp9SjeSdrpD1xAj/B0+RJMWQWIFsfdQn1AQP1UVMnkfdakTiLgxA==", "dev": true }, "@vue/cli-plugin-babel": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@vue/cli-plugin-babel/-/cli-plugin-babel-4.3.1.tgz", - "integrity": "sha512-tBqu0v1l4LfWX8xuJmofpp+8xQzKddFNxdLmeVDOX/omDBQX0qaVDeMUtRxxSTazI06SKr605SnUQoa35qwbvw==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-babel/-/cli-plugin-babel-4.5.4.tgz", + "integrity": "sha512-pXEzj/vkl3qOs/brhgxAu37hULCOHcOLzYKF747r1oudJq0aV1TOnQzTrP8aCE/A1CnW4Dbw/l9bt20a7btDcg==", "dev": true, "requires": { - "@babel/core": "^7.9.0", - "@vue/babel-preset-app": "^4.3.1", - "@vue/cli-shared-utils": "^4.3.1", + "@babel/core": "^7.11.0", + "@vue/babel-preset-app": "^4.5.4", + "@vue/cli-shared-utils": "^4.5.4", "babel-loader": "^8.1.0", "cache-loader": "^4.1.0", "thread-loader": "^2.1.3", "webpack": "^4.0.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/core": { + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.4.tgz", + "integrity": "sha512-5deljj5HlqRXN+5oJTY7Zs37iH3z3b++KjiKtIsJy1NrjOOVSEaJHEetLBhyu0aQOSNNZ/0IuEAan9GzRuDXHg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.4", + "@babel/helper-module-transforms": "^7.11.0", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.11.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.11.0", + "@babel/types": "^7.11.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.4.tgz", + "integrity": "sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", + "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/template": "^7.10.4", + "@babel/types": "^7.11.0", + "lodash": "^4.17.19" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz", + "integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", + "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.0", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.0", + "@babel/types": "^7.11.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@vue/cli-plugin-eslint": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@vue/cli-plugin-eslint/-/cli-plugin-eslint-4.3.1.tgz", - "integrity": "sha512-5UEP93b8C/JQs9Rnuldsu8jMz0XO4wNXG0lL/GdChYBEheKCyXJXzan7qzEbIuvUwG3I+qlUkGsiyNokIgXejg==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-eslint/-/cli-plugin-eslint-4.5.4.tgz", + "integrity": "sha512-mWuhKtxMiAM70nPW/NnoWtf32YJoOPPt7SyNmsAjBKSRPcje+16Egl7BD8yuPKoF1MTkvs5CM/e7gp3AnSTFzQ==", "dev": true, "requires": { - "@vue/cli-shared-utils": "^4.3.1", + "@vue/cli-shared-utils": "^4.5.4", "eslint-loader": "^2.2.1", "globby": "^9.2.0", "inquirer": "^7.1.0", @@ -1742,84 +4117,297 @@ } }, "@vue/cli-plugin-router": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@vue/cli-plugin-router/-/cli-plugin-router-4.3.1.tgz", - "integrity": "sha512-m0ntr5R6q62oNMODgoyHAVAd/sDtsH15GdBrScZsPNeyHxmzmNBDlsNM38yYGGY064zDRRWif15d1yaTREybrA==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-router/-/cli-plugin-router-4.5.4.tgz", + "integrity": "sha512-9/qRICZbq1qucq9M9z6jYT5UWNvcTu9BgHtXgsaK9gJsdmpxDIfD0SvW9nzZaHb8xxixvDRotMM/0Juw2oCsKQ==", "dev": true, "requires": { - "@vue/cli-shared-utils": "^4.3.1" + "@vue/cli-shared-utils": "^4.5.4" } }, - "@vue/cli-plugin-vuex": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.3.1.tgz", - "integrity": "sha512-mukwOlhZGBJhkqO2b3wHFFHjK5aP00b1WUHdrOfLR7M18euhaTyb4kA5nwZwEOmU3EzZx6kHzSFCRy/XaMkLug==", - "dev": true - }, - "@vue/cli-service": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@vue/cli-service/-/cli-service-4.3.1.tgz", - "integrity": "sha512-CsNGfHe+9oKZdRwJmweQ0KsMYM27ssg1eNQqRKL/t+IgDLO3Tu86uaOOCLn4ZAaU5oxxpq4aSFvz+A0YxQRSWw==", + "@vue/cli-plugin-unit-jest": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-unit-jest/-/cli-plugin-unit-jest-4.5.4.tgz", + "integrity": "sha512-ben2WsKvEEN0r96nOWsarwelNVRrC7dUZtbnXVzRKYrxfiGL9evbbdIMdNcqN7MP0lAWnn8zrH5ruEhRuhMw4A==", "dev": true, "requires": { - "@intervolga/optimize-cssnano-plugin": "^1.0.5", - "@soda/friendly-errors-webpack-plugin": "^1.7.1", - "@soda/get-current-script": "^1.0.0", - "@vue/cli-overlay": "^4.3.1", - "@vue/cli-plugin-router": "^4.3.1", - "@vue/cli-plugin-vuex": "^4.3.1", - "@vue/cli-shared-utils": "^4.3.1", - "@vue/component-compiler-utils": "^3.0.2", - "@vue/preload-webpack-plugin": "^1.1.0", - "@vue/web-component-wrapper": "^1.2.0", - "acorn": "^7.1.0", - "acorn-walk": "^7.1.1", - "address": "^1.1.2", - "autoprefixer": "^9.7.5", - "browserslist": "^4.11.1", - "cache-loader": "^4.1.0", - "case-sensitive-paths-webpack-plugin": "^2.3.0", - "cli-highlight": "^2.1.4", - "clipboardy": "^2.3.0", - "cliui": "^6.0.0", - "copy-webpack-plugin": "^5.1.1", - "css-loader": "^3.4.2", - "cssnano": "^4.1.10", - "debug": "^4.1.1", - "default-gateway": "^5.0.5", - "dotenv": "^8.2.0", - "dotenv-expand": "^5.1.0", - "file-loader": "^4.2.0", - "fs-extra": "^7.0.1", - "globby": "^9.2.0", - "hash-sum": "^2.0.0", - "html-webpack-plugin": "^3.2.0", - "launch-editor-middleware": "^2.2.1", - "lodash.defaultsdeep": "^4.6.1", - "lodash.mapvalues": "^4.6.0", - "lodash.transform": "^4.6.0", - "mini-css-extract-plugin": "^0.9.0", - "minimist": "^1.2.5", + "@babel/core": "^7.11.0", + "@babel/plugin-transform-modules-commonjs": "^7.9.6", + "@types/jest": "^24.0.19", + "@vue/cli-shared-utils": "^4.5.4", + "babel-core": "^7.0.0-bridge.0", + "babel-jest": "^24.9.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", + "deepmerge": "^4.2.2", + "jest": "^24.9.0", + "jest-environment-jsdom-fifteen": "^1.0.2", + "jest-serializer-vue": "^2.0.2", + "jest-transform-stub": "^2.0.0", + "jest-watch-typeahead": "^0.4.2", + "ts-jest": "^24.2.0", + "vue-jest": "^3.0.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/core": { + "version": "7.11.1", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.1.tgz", + "integrity": "sha512-XqF7F6FWQdKGGWAzGELL+aCO1p+lRY5Tj5/tbT3St1G8NaH70jhhDIKknIZaDans0OQBG5wRAldROLHSt44BgQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.0", + "@babel/helper-module-transforms": "^7.11.0", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.11.1", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.11.0", + "@babel/types": "^7.11.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz", + "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", + "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/template": "^7.10.4", + "@babel/types": "^7.11.0", + "lodash": "^4.17.19" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.11.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz", + "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==", + "dev": true + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", + "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.0", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.0", + "@babel/types": "^7.11.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "@vue/cli-shared-utils": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@vue/cli-shared-utils/-/cli-shared-utils-4.5.4.tgz", + "integrity": "sha512-7ZwAvGxl5szGuaJCc4jdPy/2Lb7oJvG847MDF+7pZ7FVl6bURwbUJjiUwL6DTxvpC4vch6B4tXfVvZFjzVP/bw==", + "dev": true, + "requires": { + "@hapi/joi": "^15.0.1", + "chalk": "^2.4.2", + "execa": "^1.0.0", + "launch-editor": "^2.2.1", + "lru-cache": "^5.1.1", + "node-ipc": "^9.1.1", + "open": "^6.3.0", + "ora": "^3.4.0", + "read-pkg": "^5.1.1", + "request": "^2.88.2", + "semver": "^6.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + } + } + }, + "@vue/cli-plugin-vuex": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.5.4.tgz", + "integrity": "sha512-X/F4E/dIRdiogKCdO4VGjUy5f4Fbxs7mu/gSi6Ubltle0eNE+tbBgLPH4r2g7GmHKNph4k39ikvfOMpXZcTFZg==", + "dev": true + }, + "@vue/cli-service": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@vue/cli-service/-/cli-service-4.5.4.tgz", + "integrity": "sha512-30zcebYno9tMvGsvZsnSPtieBvU5H3CkRW1JgiBmPG3Fcxp3BGSAy82Dl1gOUEj1VsAUqXWKMWX6frkYldi8UA==", + "dev": true, + "requires": { + "@intervolga/optimize-cssnano-plugin": "^1.0.5", + "@soda/friendly-errors-webpack-plugin": "^1.7.1", + "@soda/get-current-script": "^1.0.0", + "@types/minimist": "^1.2.0", + "@types/webpack": "^4.0.0", + "@types/webpack-dev-server": "^3.11.0", + "@vue/cli-overlay": "^4.5.4", + "@vue/cli-plugin-router": "^4.5.4", + "@vue/cli-plugin-vuex": "^4.5.4", + "@vue/cli-shared-utils": "^4.5.4", + "@vue/component-compiler-utils": "^3.1.2", + "@vue/preload-webpack-plugin": "^1.1.0", + "@vue/web-component-wrapper": "^1.2.0", + "acorn": "^7.4.0", + "acorn-walk": "^7.1.1", + "address": "^1.1.2", + "autoprefixer": "^9.8.6", + "browserslist": "^4.12.0", + "cache-loader": "^4.1.0", + "case-sensitive-paths-webpack-plugin": "^2.3.0", + "cli-highlight": "^2.1.4", + "clipboardy": "^2.3.0", + "cliui": "^6.0.0", + "copy-webpack-plugin": "^5.1.1", + "css-loader": "^3.5.3", + "cssnano": "^4.1.10", + "debug": "^4.1.1", + "default-gateway": "^5.0.5", + "dotenv": "^8.2.0", + "dotenv-expand": "^5.1.0", + "file-loader": "^4.2.0", + "fs-extra": "^7.0.1", + "globby": "^9.2.0", + "hash-sum": "^2.0.0", + "html-webpack-plugin": "^3.2.0", + "launch-editor-middleware": "^2.2.1", + "lodash.defaultsdeep": "^4.6.1", + "lodash.mapvalues": "^4.6.0", + "lodash.transform": "^4.6.0", + "mini-css-extract-plugin": "^0.9.0", + "minimist": "^1.2.5", "pnp-webpack-plugin": "^1.6.4", - "portfinder": "^1.0.25", + "portfinder": "^1.0.26", "postcss-loader": "^3.0.0", "ssri": "^7.1.0", - "terser-webpack-plugin": "^2.3.5", + "terser-webpack-plugin": "^2.3.6", "thread-loader": "^2.1.3", "url-loader": "^2.2.0", - "vue-loader": "^15.9.1", + "vue-loader": "^15.9.2", + "vue-loader-v16": "npm:vue-loader@^16.0.0-beta.3", "vue-style-loader": "^4.1.2", "webpack": "^4.0.0", - "webpack-bundle-analyzer": "^3.6.1", + "webpack-bundle-analyzer": "^3.8.0", "webpack-chain": "^6.4.0", - "webpack-dev-server": "^3.10.3", + "webpack-dev-server": "^3.11.0", "webpack-merge": "^4.2.2" }, "dependencies": { "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", + "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", "dev": true }, "cacache": { @@ -1869,17 +4457,6 @@ "path-exists": "^4.0.0" } }, - "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" - } - }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -1898,15 +4475,6 @@ "semver": "^6.0.0" } }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, "p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", @@ -1916,12 +4484,6 @@ "p-limit": "^2.2.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -1943,12 +4505,6 @@ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, - "serialize-javascript": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.0.0.tgz", - "integrity": "sha512-skZcHYw2vEX4bw90nAr2iTTsz6x2SrHEnfxgKYmZlvJYBEZrvbKtobJWlQ20zczKb3bsHHXXTYt48zBA7ni9cw==", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1966,9 +4522,9 @@ } }, "terser-webpack-plugin": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.6.tgz", - "integrity": "sha512-I8IDsQwZrqjdmOicNeE8L/MhwatAap3mUrtcAKJuilsemUNcX+Hier/eAzwStVqhlCxq0aG3ni9bK/0BESXkTg==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz", + "integrity": "sha512-/fKw3R+hWyHfYx7Bv6oPqmk4HGQcrWLtV3X6ggvPuwPNHSnzvVV51z6OaaCOus4YLjutYGOz3pEpbhe6Up2s1w==", "dev": true, "requires": { "cacache": "^13.0.1", @@ -1976,7 +4532,7 @@ "jest-worker": "^25.4.0", "p-limit": "^2.3.0", "schema-utils": "^2.6.6", - "serialize-javascript": "^3.0.0", + "serialize-javascript": "^4.0.0", "source-map": "^0.6.1", "terser": "^4.6.12", "webpack-sources": "^1.4.3" @@ -1985,9 +4541,9 @@ } }, "@vue/cli-shared-utils": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@vue/cli-shared-utils/-/cli-shared-utils-4.3.1.tgz", - "integrity": "sha512-lcfRalou7Z9jZgIh9PeTIpwDK7RIjr9OxfLGwbdR8czUZYUeUa67zVEMJD0OPYh/CCoREtzNbVfLPb/IYYxWEA==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@vue/cli-shared-utils/-/cli-shared-utils-4.5.4.tgz", + "integrity": "sha512-7ZwAvGxl5szGuaJCc4jdPy/2Lb7oJvG847MDF+7pZ7FVl6bURwbUJjiUwL6DTxvpC4vch6B4tXfVvZFjzVP/bw==", "dev": true, "requires": { "@hapi/joi": "^15.0.1", @@ -2000,7 +4556,6 @@ "ora": "^3.4.0", "read-pkg": "^5.1.1", "request": "^2.88.2", - "request-promise-native": "^1.0.8", "semver": "^6.1.0", "strip-ansi": "^6.0.0" }, @@ -2014,9 +4569,9 @@ } }, "@vue/component-compiler-utils": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.1.2.tgz", - "integrity": "sha512-QLq9z8m79mCinpaEeSURhnNCN6djxpHw0lpP/bodMlt5kALfONpryMthvnrQOlTcIKoF+VoPi+lPHUYeDFPXug==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.2.0.tgz", + "integrity": "sha512-lejBLa7xAMsfiZfNp7Kv51zOzifnb29FwdnMLa96z26kXErPFioSf9BMcePVIQ6/Gc6/mC0UrPpxAWIHyae0vw==", "dev": true, "requires": { "consolidate": "^0.15.1", @@ -2077,11 +4632,22 @@ } }, "@vue/preload-webpack-plugin": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.1.tgz", - "integrity": "sha512-8VCoJeeH8tCkzhkpfOkt+abALQkS11OIHhte5MBzYaKMTqK0A3ZAKEUVAffsOklhEv7t0yrQt696Opnu9oAx+w==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.2.tgz", + "integrity": "sha512-LIZMuJk38pk9U9Ur4YzHjlIyMuxPlACdBIHH9/nGYVTsaGKOSnSuELiE8vS9wa+dJpIYspYUOqk+L1Q4pgHQHQ==", "dev": true }, + "@vue/test-utils": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-1.0.4.tgz", + "integrity": "sha512-uIdDqFauzNJWlhltLSZU+P3uHEgUQczklSv2b1EKC7JzxBg9OY/5sx8UyuJwBD+zuxidhFZ4SjTuPgr8cdf63w==", + "dev": true, + "requires": { + "dom-event-types": "^1.0.0", + "lodash": "^4.17.15", + "pretty": "^2.0.0" + } + }, "@vue/web-component-wrapper": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@vue/web-component-wrapper/-/web-component-wrapper-1.2.0.tgz", @@ -2275,276 +4841,806 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, - "@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", - "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.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", - "dev": true - }, - "acorn-jsx": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", - "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", - "dev": true - }, - "acorn-walk": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", - "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==", - "dev": true - }, - "address": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", - "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", - "dev": true - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "aggregate-error": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", - "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", - "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.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.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "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-align": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", - "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "@yarnpkg/core": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@yarnpkg/core/-/core-2.1.1.tgz", + "integrity": "sha512-qeBxz8nHjKAbGTP2ZcXBnXGfM7+cN0A73mIai/24uru1ayvCIgfjWL1uIj/MM+m+K5lJX0Dcn94ZBHWits9JWQ==", "dev": true, "requires": { - "string-width": "^3.0.0" + "@arcanis/slice-ansi": "^1.0.2", + "@yarnpkg/fslib": "^2.1.0", + "@yarnpkg/json-proxy": "^2.1.0", + "@yarnpkg/libzip": "^2.1.0", + "@yarnpkg/parsers": "^2.1.0", + "@yarnpkg/pnp": "^2.1.0", + "@yarnpkg/shell": "^2.1.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "ci-info": "^2.0.0", + "clipanion": "^2.4.2", + "cross-spawn": "7.0.3", + "diff": "^4.0.1", + "globby": "^10.0.1", + "got": "^11.1.3", + "json-file-plus": "^3.3.1", + "logic-solver": "^2.0.1", + "micromatch": "^4.0.2", + "mkdirp": "^0.5.1", + "p-limit": "^2.2.0", + "pluralize": "^7.0.0", + "pretty-bytes": "^5.1.0", + "semver": "^7.1.2", + "stream-to-promise": "^2.2.0", + "tar": "^4.4.6", + "tslib": "^1.13.0", + "tunnel": "^0.0.6" }, "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", "dev": true }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "fill-range": "^7.0.1" } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" } } } }, - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true - }, - "ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "@yarnpkg/fslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.1.0.tgz", + "integrity": "sha512-E+f8w5yQZnTf1soyTWy7qdf+GmHsY+A0yEN4Di44/Txk6XRIMruyc1ShDi93mOI6ilnXxD87rNms18zJ8WnspA==", "dev": true, "requires": { - "type-fest": "^0.11.0" + "@yarnpkg/libzip": "^2.1.0", + "tslib": "^1.13.0" }, "dependencies": { - "type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", "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": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "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==", + "@yarnpkg/json-proxy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/json-proxy/-/json-proxy-2.1.0.tgz", + "integrity": "sha512-rOgCg2DkyviLgr80mUMTt9vzdf5RGOujQB26yPiXjlz4WNePLBshKlTNG9rKSoKQSOYEQcw6cUmosfOKDatrCw==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "@yarnpkg/fslib": "^2.1.0", + "tslib": "^1.13.0" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } } }, - "ansicolors": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=", - "dev": true + "@yarnpkg/libzip": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/libzip/-/libzip-2.1.0.tgz", + "integrity": "sha512-39c7KuSWcYUqVxlBLZwfqdD/D6lS+jplNVWd6uAnk8EpnacaYGJRegvkqWyfw5c8KHukNMeEGF5JHrXPZYBM0w==", + "dev": true, + "requires": { + "@types/emscripten": "^1.38.0", + "tslib": "^1.13.0" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } + } }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", + "@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", "dev": true }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "@yarnpkg/parsers": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-2.1.0.tgz", + "integrity": "sha512-75OYQ6PMs1C3zm+W+T1xhLyVDX78zXQGEVHpWd4o/QwpAbhneB3/5FXVGRzI3gjPPWWSb/pKOPB1S6p0xmQD2Q==", "dev": true, "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "js-yaml": "^3.10.0", + "tslib": "^1.13.0" }, "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } + } + }, + "@yarnpkg/pnp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/pnp/-/pnp-2.1.0.tgz", + "integrity": "sha512-b8NlB71EFifv1jDX47nFaRXrykROxHcS7YuGb2dQ+Gp9gqJ0thIaZ3yB9+qWF8acdWtNcMpjCug4xkfAAR5Odw==", + "dev": true, + "requires": { + "@types/node": "^13.7.0", + "@yarnpkg/fslib": "^2.1.0", + "tslib": "^1.13.0" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } + } + }, + "@yarnpkg/shell": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/shell/-/shell-2.1.0.tgz", + "integrity": "sha512-9i9ZWqeKHGV0DOfdxTVq5zl73Li8Fg947v57uLBEaytNF+HywkDfouNkg/6HfgBrpI0WH8OJ9Pz/uDaE5cpctw==", + "dev": true, + "requires": { + "@yarnpkg/fslib": "^2.1.0", + "@yarnpkg/parsers": "^2.1.0", + "clipanion": "^2.4.2", + "cross-spawn": "7.0.3", + "fast-glob": "^3.2.2", + "stream-buffers": "^3.0.2", + "tslib": "^1.13.0" + }, + "dependencies": { + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { - "remove-trailing-separator": "^1.0.1" + "fill-range": "^7.0.1" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.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==", + "abab": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.4.tgz", + "integrity": "sha512-Eu9ELJWCz/c1e9gTiCY+FceWxcqzjYEbqMgtndnuSqZSUCOL73TWNK2mHfIj4Cw2E/ongOp+JISVNCmovt2KYQ==", "dev": true }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "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 }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", "dev": true, "requires": { - "sprintf-js": "~1.0.2" + "mime-types": "~2.1.24", + "negotiator": "0.6.2" } }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "acorn": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", "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==", + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "dev": true, + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "dev": true + } + } + }, + "acorn-jsx": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", + "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", "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=", + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "address": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", + "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", "dev": true }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.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.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "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-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "dev": true, + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "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": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "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" + } + }, + "ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=", + "dev": true + }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", + "dev": true + }, + "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" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.2.tgz", + "integrity": "sha512-NTBIIbAfkJeIletyABbVtdPgeKfDafR+1mZV/AyyfC1UkVkp9iUjV+wwmqtUgphHYajbI86jejBJp5e+jkGTiQ==", + "dev": true + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "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-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "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" @@ -2584,14 +5680,23 @@ } }, "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", "dev": true, "requires": { "bn.js": "^4.0.0", "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "assert": { @@ -2679,18 +5784,46 @@ "dev": true }, "autoprefixer": { - "version": "9.7.6", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.6.tgz", - "integrity": "sha512-F7cYpbN7uVVhACZTeeIeealwdGM6wMtfWARVLTy5xmKtgVdBNJvbDRoCK3YO1orcs7gv/KwYlb3iXwu9Ug9BkQ==", + "version": "9.8.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", + "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==", "dev": true, "requires": { - "browserslist": "^4.11.1", - "caniuse-lite": "^1.0.30001039", - "chalk": "^2.4.2", + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001109", + "colorette": "^1.2.1", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", - "postcss": "^7.0.27", - "postcss-value-parser": "^4.0.3" + "postcss": "^7.0.32", + "postcss-value-parser": "^4.1.0" + }, + "dependencies": { + "postcss": { + "version": "7.0.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", + "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.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 + }, + "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" + } + } } }, "aws-sign2": { @@ -2700,42 +5833,84 @@ "dev": true }, "aws4": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", "dev": true }, "axios": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", - "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz", + "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "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": { - "follow-redirects": "1.5.10" + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" }, "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "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": { - "ms": "2.0.0" + "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" } }, - "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "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": { - "debug": "=3.1.0" + "ansi-regex": "^2.0.0" } }, - "ms": { + "supports-color": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "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-eslint": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", @@ -2750,6 +5925,21 @@ "resolve": "^1.12.0" } }, + "babel-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", + "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", + "dev": true, + "requires": { + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/babel__core": "^7.1.0", + "babel-plugin-istanbul": "^5.1.0", + "babel-preset-jest": "^24.9.0", + "chalk": "^2.4.2", + "slash": "^2.0.0" + } + }, "babel-loader": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", @@ -2763,6 +5953,15 @@ "schema-utils": "^2.6.5" } }, + "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.3.3", "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", @@ -2772,6 +5971,162 @@ "object.assign": "^4.1.0" } }, + "babel-plugin-istanbul": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", + "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "find-up": "^3.0.0", + "istanbul-lib-instrument": "^3.3.0", + "test-exclude": "^5.2.3" + } + }, + "babel-plugin-jest-hoist": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", + "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", + "dev": true, + "requires": { + "@types/babel__traverse": "^7.0.6" + } + }, + "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-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-preset-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", + "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", + "dev": true, + "requires": { + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "babel-plugin-jest-hoist": "^24.9.0" + } + }, + "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": { + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "dev": true + }, + "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 + }, "bail": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", @@ -2889,7 +6244,6 @@ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", "dev": true, - "optional": true, "requires": { "file-uri-to-path": "1.0.0" } @@ -2935,9 +6289,9 @@ "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==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", + "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", "dev": true }, "body-parser": { @@ -3128,6 +6482,29 @@ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", "dev": true }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "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", @@ -3173,21 +6550,50 @@ "requires": { "bn.js": "^4.1.0", "randombytes": "^2.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", "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" + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } } }, "browserify-zlib": { @@ -3200,15 +6606,33 @@ } }, "browserslist": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz", - "integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.0.tgz", + "integrity": "sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001111", + "electron-to-chromium": "^1.3.523", + "escalade": "^3.0.2", + "node-releases": "^1.1.60" + } + }, + "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.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001043", - "electron-to-chromium": "^1.3.413", - "node-releases": "^1.1.53", - "pkg-up": "^2.0.0" + "node-int64": "^0.4.0" } }, "buffer": { @@ -3351,15 +6775,6 @@ "semver": "^6.0.0" } }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, "p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", @@ -3369,12 +6784,6 @@ "p-limit": "^2.2.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -3398,25 +6807,31 @@ } } }, + "cacheable-lookup": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz", + "integrity": "sha512-W+JBqF9SWe18A72XFzN/V/CULFzPm7sBXzzR6ekkE+3tLG72wFZrBiBZhrZuDoYexop4PHJVdFAKb/Nj9+tm9w==", + "dev": true + }, "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.1.tgz", + "integrity": "sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==", "dev": true, "requires": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", + "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", "normalize-url": "^4.1.0", - "responselike": "^1.0.2" + "responselike": "^2.0.0" }, "dependencies": { "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -3495,11 +6910,20 @@ } }, "caniuse-lite": { - "version": "1.0.30001048", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001048.tgz", - "integrity": "sha512-g1iSHKVxornw0K8LG9LLdf+Fxnv7T1Z+mMsf0/YYLclQX4Cd522Ap0Lrw6NFqHgezit78dtyWxzlV2Xfc7vgRg==", + "version": "1.0.30001116", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001116.tgz", + "integrity": "sha512-f2lcYnmAI5Mst9+g0nkMIznFGsArRmZ0qU+dnq8l91hymdc2J3SFbiPhOJEeDqC1vtE8nc1qNQyklzB8veJefQ==", "dev": true }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "requires": { + "rsvp": "^4.8.4" + } + }, "case-sensitive-paths-webpack-plugin": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz", @@ -3553,6 +6977,12 @@ "integrity": "sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ==", "dev": true }, + "child-process": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/child-process/-/child-process-1.0.2.tgz", + "integrity": "sha1-mJdNx+0e5MYin44wX6cxOmiFp/I=", + "dev": true + }, "chokidar": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", @@ -3571,6 +7001,19 @@ "path-is-absolute": "^1.0.0", "readdirp": "^2.2.1", "upath": "^1.1.1" + }, + "dependencies": { + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } + } } }, "chownr": { @@ -3758,6 +7201,12 @@ "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", "dev": true }, + "clipanion": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/clipanion/-/clipanion-2.4.4.tgz", + "integrity": "sha512-KjyCBz8xplftHjIK/nOqq/9b3hPlXbAAo/AxoITrO4yySpQ6a9QSJDAfOx9PfcRUHteeqbdNxZKSPfeFqQ7plg==", + "dev": true + }, "clipboardy": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz", @@ -3770,10 +7219,13 @@ }, "dependencies": { "is-wsl": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.1.tgz", - "integrity": "sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog==", - "dev": true + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } } } }, @@ -3794,17 +7246,6 @@ "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", "dev": true }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, "clone-response": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", @@ -3888,6 +7329,12 @@ "simple-swizzle": "^0.2.2" } }, + "colorette": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", + "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -3986,23 +7433,64 @@ "typedarray": "^0.0.6" } }, - "configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "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": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" + "extend-shallow": "^2.0.1", + "is-whitespace": "^0.3.0", + "kind-of": "^3.0.2" }, "dependencies": { - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "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" + } + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "requires": { @@ -4140,21 +7628,6 @@ "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", "dev": true }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", @@ -4172,6 +7645,12 @@ "ajv-keywords": "^3.1.0" } }, + "serialize-javascript": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", + "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", + "dev": true + }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", @@ -4234,13 +7713,21 @@ } }, "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", "dev": true, "requires": { "bn.js": "^4.1.0", - "elliptic": "^6.0.0" + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "create-hash": { @@ -4345,9 +7832,9 @@ } }, "css-loader": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.5.3.tgz", - "integrity": "sha512-UEr9NH5Lmi7+dguAm+/JSPovNjYbm2k3TK58EiwQHzOHH5Jfq1Y+XoP2bQO6TMn7PptMd0opxxedAWcaSTRKHw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", + "integrity": "sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==", "dev": true, "requires": { "camelcase": "^5.3.1", @@ -4355,21 +7842,58 @@ "icss-utils": "^4.1.1", "loader-utils": "^1.2.3", "normalize-path": "^3.0.0", - "postcss": "^7.0.27", + "postcss": "^7.0.32", "postcss-modules-extract-imports": "^2.0.0", "postcss-modules-local-by-default": "^3.0.2", "postcss-modules-scope": "^2.2.0", "postcss-modules-values": "^3.0.0", - "postcss-value-parser": "^4.0.3", - "schema-utils": "^2.6.6", + "postcss-value-parser": "^4.1.0", + "schema-utils": "^2.7.0", "semver": "^6.3.0" }, "dependencies": { + "postcss": { + "version": "7.0.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", + "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "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 + }, + "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" + } } } }, @@ -4419,9 +7943,9 @@ } }, "css-what": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.2.1.tgz", - "integrity": "sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz", + "integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==", "dev": true }, "cssesc": { @@ -4540,6 +8064,21 @@ } } }, + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "cssstyle": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", + "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", + "dev": true, + "requires": { + "cssom": "0.3.x" + } + }, "cyclist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", @@ -4561,12 +8100,46 @@ "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==", "dev": true }, + "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.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + } + } + }, "de-indent": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", "dev": true }, + "deasync": { + "version": "0.1.20", + "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.20.tgz", + "integrity": "sha512-E1GI7jMI57hL30OX6Ht/hfQU8DO4AuB9m72WFm4c38GNbUD4Q03//XZaOIHZiY+H1xUaomcot5yk2q/qIZQkGQ==", + "dev": true, + "requires": { + "bindings": "^1.5.0", + "node-addon-api": "^1.7.1" + } + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -4589,12 +8162,20 @@ "dev": true }, "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dev": true, "requires": { - "mimic-response": "^1.0.0" + "mimic-response": "^3.1.0" + }, + "dependencies": { + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true + } } }, "deep-equal": { @@ -4639,9 +8220,9 @@ }, "dependencies": { "cross-spawn": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz", - "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -4668,9 +8249,9 @@ } }, "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -4698,9 +8279,9 @@ } }, "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { "mimic-fn": "^2.1.0" @@ -4754,9 +8335,9 @@ } }, "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.0.tgz", + "integrity": "sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg==", "dev": true }, "define-properties": { @@ -4930,6 +8511,12 @@ "integrity": "sha512-Uv3SW8bmH9nAtHKaKSanOQmj2DnlH65fUpcrMdfdaOxUG02QQ4YGZ8AE7kKOMisF7UqvOlGKVYWRvezdncW9lg==", "dev": true }, + "diff-sequences": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", + "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==", + "dev": true + }, "diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -4939,6 +8526,14 @@ "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "dir-glob": { @@ -5027,6 +8622,12 @@ "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.2.2", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", @@ -5057,6 +8658,15 @@ "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.4.2", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", @@ -5119,9 +8729,9 @@ } }, "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "dev": true }, "duplexer3": { @@ -5158,6 +8768,36 @@ "safer-buffer": "^2.1.0" } }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "dev": true, + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "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", @@ -5171,15 +8811,15 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.427", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.427.tgz", - "integrity": "sha512-/rG5G7Opcw68/Yrb4qYkz07h3bESVRJjUl4X/FrKLXzoUJleKm6D7K7rTTz8V5LUWnd+BbTOyxJX2XprRqHD8A==", + "version": "1.3.540", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.540.tgz", + "integrity": "sha512-IoGiZb8SMqTtkDYJtP8EtCdvv3VMtd1QoTlypO2RUBxRq/Wk0rU5IzhzhMckPaC9XxDqUvWsL0XKOBhTiYVN3w==", "dev": true }, "elliptic": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", - "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", "dev": true, "requires": { "bn.js": "^4.4.0", @@ -5189,6 +8829,14 @@ "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0", "minimalistic-crypto-utils": "^1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "email-validator": { @@ -5225,9 +8873,9 @@ } }, "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz", + "integrity": "sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -5247,6 +8895,23 @@ } } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + }, + "dependencies": { + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + } + } + }, "entities": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", @@ -5281,22 +8946,22 @@ } }, "es-abstract": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", - "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", "object-inspect": "^1.7.0", "object-keys": "^1.1.1", "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" } }, "es-to-primitive": { @@ -5325,6 +8990,12 @@ "es6-promise": "^4.0.3" } }, + "escalade": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.2.tgz", + "integrity": "sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ==", + "dev": true + }, "escape-goat": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", @@ -5366,22 +9037,23 @@ } }, "eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.7.0.tgz", + "integrity": "sha512-1KUxLzos0ZVsyL81PnRN335nDtQ8/vZUD6uMtWbF+5zDtjKcsklIi78XoE0MVL93QvWTu+E5y44VyyCsOMBrIg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.0", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^1.3.0", + "espree": "^7.2.0", + "esquery": "^1.2.0", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", @@ -5390,83 +9062,216 @@ "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", + "levn": "^0.4.1", + "lodash": "^4.17.19", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.3", + "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", "table": "^5.2.3", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { - "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "acorn": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", + "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" } }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "requires": { - "is-glob": "^4.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "type-fest": "^0.8.1" + "color-name": "~1.1.4" } }, - "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "eslint-scope": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "espree": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.2.0.tgz", + "integrity": "sha512-H+cQ3+3JYRMEIOl87e7QdHX70ocly5iW4+dttuR8iYSPr/hXKFb+7dBsZ7+u1adC4VrnPlTkv0+OwuPnDop19g==", + "dev": true, + "requires": { + "acorn": "^7.3.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.3.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" } }, "type-fest": { @@ -5474,6 +9279,15 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -5488,32 +9302,32 @@ } }, "eslint-config-adjunct": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/eslint-config-adjunct/-/eslint-config-adjunct-4.8.4.tgz", - "integrity": "sha512-LfN6Ob7x9MCOAYiXbbvazzT75hmWurbqJKccgCr+1Nt8vIpURjDEJ4y9t3NzR2xQvu1LicftiN+RQnSjbNbLpA==", + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/eslint-config-adjunct/-/eslint-config-adjunct-4.8.5.tgz", + "integrity": "sha512-S1u7vtmbCL6SKrKrQr/pF5yAixF26pGaqBzn+KL2t8CQvc1w7feHHWfR45Ts4PfofeeXnZ4mzi1x1AmhUZGqxA==", "dev": true, "requires": { "arrify": "^2.0.1", - "cosmiconfig": "^6.0.0", - "lodash": "^4.17.15", + "cosmiconfig": "^7.0.0", + "lodash": "^4.17.20", "mkdirp": "^1.0.4", - "ramda": "^0.27.0", + "ramda": "^0.27.1", "read-pkg-up": "^7.0.1", "rimraf": "^3.0.2", - "snyk": "^1.346.0" + "snyk": "^1.381.1" }, "dependencies": { "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", "dev": true, "requires": { "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", + "import-fresh": "^3.2.1", "parse-json": "^5.0.0", "path-type": "^4.0.0", - "yaml": "^1.7.2" + "yaml": "^1.10.0" } }, "import-fresh": { @@ -5526,6 +9340,12 @@ "resolve-from": "^4.0.0" } }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true + }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -5578,9 +9398,9 @@ } }, "eslint-plugin-array-func": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-array-func/-/eslint-plugin-array-func-3.1.6.tgz", - "integrity": "sha512-heMql4APbpZx4QFZTwVHGepR0JaxSlflaJa2kCVy+zUrVFhYmGVuDcAqEROcxMHYKleqwKkQ57515c7Uadc5nQ==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/eslint-plugin-array-func/-/eslint-plugin-array-func-3.1.7.tgz", + "integrity": "sha512-fB5TBICjHSTGToNTbCCgR8zsngpUkoCM31EMh/M/NEAyNg90i5rUuG0dnNNBML2n0BzM0nBE3sPvo2SEWf6jlA==", "dev": true }, "eslint-plugin-eslint-comments": { @@ -5602,9 +9422,9 @@ } }, "eslint-plugin-html": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-6.0.2.tgz", - "integrity": "sha512-Ik/z32UteKLo8GEfwNqVKcJ/WOz/be4h8N5mbMmxxnZ+9aL9XczOXQFz/bGu+nAGVoRg8CflldxJhONFpqlrxw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-6.0.3.tgz", + "integrity": "sha512-1KV2ebQHywlXkfpXOGjxuEyoq+g6AWvD6g9TB28KsGhbM5rJeHXAEpHOev6LqZv6ylcfa9BWokDsNVKyYefzGw==", "dev": true, "requires": { "htmlparser2": "^4.1.0" @@ -5650,14 +9470,48 @@ } } }, + "eslint-plugin-jest": { + "version": "23.20.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.20.0.tgz", + "integrity": "sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "^2.5.0" + } + }, + "eslint-plugin-jest-async": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest-async/-/eslint-plugin-jest-async-1.0.3.tgz", + "integrity": "sha1-aRlnAtivhWVbIaeJpv11ygo3gA8=", + "dev": true, + "requires": { + "requireindex": "~1.1.0" + }, + "dependencies": { + "requireindex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.1.0.tgz", + "integrity": "sha1-5UBLgVV+91225JxacgBIk/4D4WI=", + "dev": true + } + } + }, "eslint-plugin-json": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-json/-/eslint-plugin-json-2.1.1.tgz", - "integrity": "sha512-Ktsab8ij33V2KFLhh4alC1FYztdmbV32DeMZYYUCZm4kKLW1s4DrleKKgtbAHSJsmshCK5QGOZtfyc2r3jCRsg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-json/-/eslint-plugin-json-2.1.2.tgz", + "integrity": "sha512-isM/fsUxS4wN1+nLsWoV5T4gLgBQnsql3nMTr8u+cEls1bL8rRQO5CP5GtxJxaOfbcKqnz401styw+H/P+e78Q==", "dev": true, "requires": { - "lodash": "^4.17.15", - "vscode-json-languageservice": "^3.5.1" + "lodash": "^4.17.19", + "vscode-json-languageservice": "^3.7.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } } }, "eslint-plugin-json-format": { @@ -5688,18 +9542,18 @@ } }, "eslint-plugin-no-constructor-bind": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-constructor-bind/-/eslint-plugin-no-constructor-bind-2.0.2.tgz", - "integrity": "sha512-IGmwmT1N4LgnUIAXuaBW0ouZUnC+FoYn0rx1KozmSjwNi8QhUJ18KtWVm5NdzQQFX4Bb0ikwm/5zlIgvodQkJw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-constructor-bind/-/eslint-plugin-no-constructor-bind-2.0.3.tgz", + "integrity": "sha512-UHMqpTvCe2NYkiZUK04BwIYe9EDnHFSjLgsfLHcfS1/3QcULSsNBixqwkuywLiA1hQWERHjpJCMGgUzwR92jnw==", "dev": true, "requires": { "requireindex": "~1.2.0" } }, "eslint-plugin-no-secrets": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-secrets/-/eslint-plugin-no-secrets-0.5.4.tgz", - "integrity": "sha512-l7BuVWcTMOwA+bqs6M3dzzbB3V0H1/sJC1X3PIuMYUybljtlny0fhpxcsyI3bSG0PoraSAWI4IX8v8AroCbIkA==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-secrets/-/eslint-plugin-no-secrets-0.6.8.tgz", + "integrity": "sha512-hX/z+V6oEFBaY6GHRYPv1mXyieq0z3oijE8C3muYhhyjICRS2Uk+RPMwK700ARkQIKFWYsezXc7hmISeqHbEZA==", "dev": true }, "eslint-plugin-no-unsanitized": { @@ -5792,23 +9646,24 @@ } }, "eslint-plugin-unicorn": { - "version": "19.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-19.0.1.tgz", - "integrity": "sha512-fu0/h5mHXfBC6EkA3i2vCjsfC8j53+T9txGhNL4fpxJ+1JKsUKfv+tmXDgy0XnLHhFjnOZp4tRWJWbcykeIP2Q==", + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-21.0.0.tgz", + "integrity": "sha512-S8v7+v4gZTQPj4pKKvexhgSUaLQSyItvxW2SVZDaX9Iu5IjlAmF2eni+L6w8a2aqshxgU8Lle4FIAVDtuejSKQ==", "dev": true, "requires": { "ci-info": "^2.0.0", "clean-regexp": "^1.0.0", "eslint-ast-utils": "^1.1.0", - "eslint-template-visitor": "^1.1.0", - "eslint-utils": "^2.0.0", + "eslint-template-visitor": "^2.0.0", + "eslint-utils": "^2.1.0", "import-modules": "^2.0.0", "lodash": "^4.17.15", + "pluralize": "^8.0.0", "read-pkg-up": "^7.0.1", "regexp-tree": "^0.1.21", "reserved-words": "^0.1.2", "safe-regex": "^2.1.1", - "semver": "^7.1.3" + "semver": "^7.3.2" }, "dependencies": { "ci-info": { @@ -5817,15 +9672,6 @@ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true }, - "eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, "safe-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", @@ -5844,45 +9690,68 @@ } }, "eslint-plugin-vue": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-6.2.2.tgz", - "integrity": "sha512-Nhc+oVAHm0uz/PkJAWscwIT4ijTrK5fqNqz9QB1D35SbbuMG1uB6Yr5AJpvPSWg+WOw7nYNswerYh0kOk64gqQ==", + "version": "7.0.0-beta.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.0.0-beta.2.tgz", + "integrity": "sha512-EpAVWT62JTM7Yo6IUJIaIvNMSuayDaMVMXv1SC96d1/7nyx18U0FrLRKpN2GdTY8Efi4UepgR75XW7ucSRiI7A==", "dev": true, "requires": { + "eslint-utils": "^2.1.0", "natural-compare": "^1.4.0", - "semver": "^5.6.0", - "vue-eslint-parser": "^7.0.0" + "semver": "^7.3.2", + "vue-eslint-parser": "^7.1.0" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "vue-eslint-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.1.0.tgz", + "integrity": "sha512-Kr21uPfthDc63nDl27AGQEhtt9VrZ9nkYk/NTftJ2ws9XiJwzJJCnCr3AITQ2jpRMA0XPGDECxYH8E027qMK9Q==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-scope": "^5.0.0", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.2.1", + "esquery": "^1.0.1", + "lodash": "^4.17.15" + } + } } }, "eslint-plugin-vue-scoped-css": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue-scoped-css/-/eslint-plugin-vue-scoped-css-0.5.0.tgz", - "integrity": "sha512-hEvgtC405AByh33spNt07aLv1PLVROOVNhaic0KfPxDn+CH4nmSoH43qgwkBMOq+mCl134Htlkxu1T/+Jpheew==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue-scoped-css/-/eslint-plugin-vue-scoped-css-1.0.0.tgz", + "integrity": "sha512-4C51QYYWVnxwmg3k6h7BouRedPmxYXt/Dijiwo6KMnYwGire8bR0dbhWZv+jtZsW+6RtN9Fq+zZdH/nQmAe4WA==", "dev": true, "requires": { - "eslint-utils": "^2.0.0", - "lodash": "^4.17.15", - "postcss": "^7.0.29", + "eslint-utils": "^2.1.0", + "lodash": "^4.17.19", + "postcss": "^7.0.32", "postcss-safe-parser": "^4.0.2", - "postcss-scss": "^2.0.0", + "postcss-scss": "^2.1.1", "postcss-selector-parser": "^6.0.2", - "postcss-styl": "^0.7.1", - "vue-eslint-parser": "^7.0.0 || ^6.0.0 || ^5.0.0" + "postcss-styl": "^0.7.1" }, "dependencies": { - "eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, "postcss": { - "version": "7.0.30", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.30.tgz", - "integrity": "sha512-nu/0m+NtIzoubO+xdAlwZl/u5S5vi/y6BCsoL8D+8IxsD3XvBS8X4YEADNIVXKVuQvduiucnRv+vPIqj56EGMQ==", + "version": "7.0.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", + "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -5918,20 +9787,29 @@ } }, "eslint-template-visitor": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-1.1.0.tgz", - "integrity": "sha512-Lmy6QVlmFiIGl5fPi+8ACnov3sare+0Ouf7deJAGGhmUfeWJ5fVarELUxZRpsZ9sHejiJUq8626d0dn9uvcZTw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.2.1.tgz", + "integrity": "sha512-q3SxoBXz0XjPGkUpwGVAwIwIPIxzCAJX1uwfVc8tW3v7u/zS7WXNH3I2Mu2MDz2NgSITAyKLRaQFPHu/iyKxDQ==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.1", - "multimap": "^1.0.2" + "babel-eslint": "^10.1.0", + "eslint-visitor-keys": "^1.3.0", + "esquery": "^1.3.1", + "multimap": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } }, "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" @@ -6013,9 +9891,9 @@ "dev": true }, "event-loop-spinner": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/event-loop-spinner/-/event-loop-spinner-1.1.0.tgz", - "integrity": "sha512-YVFs6dPpZIgH665kKckDktEVvSBccSYJmoZUfhNUdv5d3Xv+Q+SKF4Xis1jolq9aBzuW1ZZhQh/m/zU/TPdDhw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/event-loop-spinner/-/event-loop-spinner-2.0.0.tgz", + "integrity": "sha512-1y4j/Mhttr8ordvHkbDsGzGrlQaSYJoXD/3YKUxiOXIk7myEn9UPfybEk/lLtrcU3D4QvCNmVUxVQaPtvAIaUw==", "dev": true, "requires": { "tslib": "^1.10.0" @@ -6034,9 +9912,9 @@ "dev": true }, "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", "dev": true }, "eventsource": { @@ -6058,6 +9936,12 @@ "safe-buffer": "^5.1.1" } }, + "exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", + "dev": true + }, "execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", @@ -6073,6 +9957,12 @@ "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", @@ -6123,6 +10013,20 @@ } } }, + "expect": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", + "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "ansi-styles": "^3.2.0", + "jest-get-type": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-regex-util": "^24.9.0" + } + }, "express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", @@ -6287,6 +10191,15 @@ } } }, + "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", @@ -6349,6 +10262,15 @@ "websocket-driver": ">=0.5.1" } }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, "figgy-pudding": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", @@ -6450,6 +10372,24 @@ } } }, + "find-babel-config": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz", + "integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==", + "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.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", @@ -6462,12 +10402,12 @@ } }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "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": "^2.0.0" + "locate-path": "^3.0.0" } }, "flat-cache": { @@ -6509,24 +10449,9 @@ } }, "follow-redirects": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.11.0.tgz", - "integrity": "sha512-KZm0V+ll8PfBrKwMzdo5D13b1bur9Iq9Zd/RMmAoQQcl2PxxFml8cxXPaaPYVbV0RjNjq1CU7zIzAOqtUPudmA==", - "dev": true, - "requires": { - "debug": "^3.0.0" - }, - "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" - } - } - } + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.12.1.tgz", + "integrity": "sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg==" }, "for-in": { "version": "1.0.2", @@ -6588,6 +10513,17 @@ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "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" + } + }, "fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -6616,655 +10552,715 @@ "dev": true }, "fsevents": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", - "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "optional": true + }, + "ftp": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", + "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", "dev": true, - "optional": true, "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1", - "node-pre-gyp": "*" - }, + "readable-stream": "1.1.x", + "xregexp": "2.0.0" + }, "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": 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, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { + "isarray": { "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "3.2.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "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.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "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.6", - "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 + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, - "optional": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" } }, - "ignore-walk": { - "version": "3.0.3", - "bundled": true, + "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 + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-set-props": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz", + "integrity": "sha1-mYR1wXhEVobQsyJG2l3428++jqM=", + "dev": true + }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "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-uri": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.4.tgz", + "integrity": "sha512-v7LT/s8kVjs+Tx0ykk1I+H/rbpzkHvuIq87LmeXptcf5sNWm9uQiwjNAt94SJPA1zOlCntmnOlJvVWKmzsxG8Q==", + "dev": true, + "requires": { + "data-uri-to-buffer": "1", + "debug": "2", + "extend": "~3.0.2", + "file-uri-to-path": "1", + "ftp": "~0.3.10", + "readable-stream": "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, - "optional": true, "requires": { - "minimatch": "^3.0.4" + "ms": "2.0.0" } }, - "inflight": { - "version": "1.0.6", - "bundled": true, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "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" + } + }, + "git-hooks-list": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-1.0.3.tgz", + "integrity": "sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "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-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, - "optional": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "is-extglob": "^2.1.0" } - }, - "inherits": { - "version": "2.0.4", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": 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, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.9.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.0", - "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.4.2" - } - }, - "nopt": { - "version": "4.0.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1", - "npm-normalize-package-bin": "^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, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": 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.1", - "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" - } - }, - "readable-stream": { - "version": "2.3.7", - "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.7.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": 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.7.1", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { + } + } + }, + "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 + }, + "global-dirs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", + "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", + "dev": true, + "requires": { + "ini": "^1.3.5" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "globby": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" + } + }, + "got": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/got/-/got-11.5.2.tgz", + "integrity": "sha512-yUhpEDLeuGiGJjRSzEq3kvt4zJtAcjKmhIiwNp/eUs75tRlXfWcHo5tcBaMQtnjHWC7nQYT5HkY/l0QOQTkVww==", + "dev": true, + "requires": { + "@sindresorhus/is": "^3.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.1", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.0", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "dependencies": { + "lowercase-keys": { "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, + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "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 + }, + "gunzip-maybe": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz", + "integrity": "sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==", + "dev": true, + "requires": { + "browserify-zlib": "^0.1.4", + "is-deflate": "^1.0.0", + "is-gzip": "^1.0.0", + "peek-stream": "^1.1.0", + "pumpify": "^1.3.3", + "through2": "^2.0.3" + }, + "dependencies": { + "browserify-zlib": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", "dev": true, - "optional": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "pako": "~0.2.0" } }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "dev": true + } + } + }, + "gzip-size": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", + "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", + "dev": true, + "requires": { + "duplexer": "^0.1.1", + "pify": "^4.0.1" + } + }, + "handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "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.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "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, - "optional": true, "requires": { - "safe-buffer": "~5.1.0" + "is-buffer": "^1.1.5" } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, + } + } + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, - "optional": true, "requires": { - "ansi-regex": "^2.0.0" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "hash-sum": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", + "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==", + "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 + }, + "highlight.js": { + "version": "9.18.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.3.tgz", + "integrity": "sha512-zBZAmhSupHIl5sITeMqIJnYCDfAEc3Gdkqj65wC1lpI468MMQeeQkhcIAvk+RylAkxrCcI9xy9piHiXeQ1BdzQ==", + "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" + } + }, + "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.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "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.3.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", + "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==", + "dev": true + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "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": "3.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", + "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", + "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 }, - "tar": { - "version": "4.4.13", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true }, - "wide-align": { - "version": "1.1.3", - "bundled": 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, - "optional": true, "requires": { - "string-width": "^1.0.2 || 2" + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" } }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.1.1", - "bundled": 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, - "optional": true + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } } } }, - "ftp": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", - "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", "dev": true, "requires": { - "readable-stream": "1.1.x", - "xregexp": "2.0.0" + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" }, "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", "dev": true }, "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } - }, - "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 } } }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", "dev": true }, - "get-set-props": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz", - "integrity": "sha1-mYR1wXhEVobQsyJG2l3428++jqM=", + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", "dev": true }, - "get-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", - "dev": true + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "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==", + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dev": true, "requires": { - "pump": "^3.0.0" + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" } }, - "get-uri": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.4.tgz", - "integrity": "sha512-v7LT/s8kVjs+Tx0ykk1I+H/rbpzkHvuIq87LmeXptcf5sNWm9uQiwjNAt94SJPA1zOlCntmnOlJvVWKmzsxG8Q==", + "http-proxy-agent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", "dev": true, "requires": { - "data-uri-to-buffer": "1", - "debug": "2", - "extend": "~3.0.2", - "file-uri-to-path": "1", - "ftp": "~0.3.10", - "readable-stream": "2" + "agent-base": "4", + "debug": "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==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -7278,1370 +11274,1778 @@ } } }, - "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=", + "http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", "dev": true, "requires": { - "assert-plus": "^1.0.0" + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" } }, - "git-hooks-list": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-1.0.3.tgz", - "integrity": "sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ==", - "dev": true + "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" + } }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "http2-wrapper": { + "version": "1.0.0-beta.5.2", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz", + "integrity": "sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ==", "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" + "quick-lru": "^5.1.1", + "resolve-alpn": "^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=", + "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 + }, + "https-proxy-agent": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz", + "integrity": "sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg==", "dev": true, "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "agent-base": "^4.3.0", + "debug": "^3.1.0" }, "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "is-extglob": "^2.1.0" + "ms": "^2.1.1" } } } }, - "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=", + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "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-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", + "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", + "dev": true, + "requires": { + "postcss": "^7.0.14" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "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": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, - "global-dirs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", - "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", + "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": { - "ini": "^1.3.5" + "import-from": "^2.1.0" } }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "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": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" } }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "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": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" + "resolve-from": "^3.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", "dev": true }, - "gunzip-maybe": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz", - "integrity": "sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==", + "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": { - "browserify-zlib": "^0.1.4", - "is-deflate": "^1.0.0", - "is-gzip": "^1.0.0", - "peek-stream": "^1.1.0", - "pumpify": "^1.3.3", - "through2": "^2.0.3" - }, - "dependencies": { - "browserify-zlib": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", - "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", - "dev": true, - "requires": { - "pako": "~0.2.0" - } - }, - "pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", - "dev": true - } + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" } }, - "gzip-size": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", - "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", - "dev": true, - "requires": { - "duplexer": "^0.1.1", - "pify": "^4.0.1" - } + "import-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-2.0.0.tgz", + "integrity": "sha512-iczM/v9drffdNnABOKwj0f9G3cFDon99VcG1mxeBsdqnbd+vnQ5c2uAiCHNQITqFTOPaEvwg3VjoWCur0uHLEw==", + "dev": true }, - "handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "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==", + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" + "once": "^1.3.0", + "wrappy": "1" } }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "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 + }, + "inquirer": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", + "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", "dev": true, "requires": { - "function-bind": "^1.1.1" + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.19", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "rxjs": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", + "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.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 + "default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + } } } }, - "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.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" + "loose-envify": "^1.0.0" } }, - "has-values": { + "invert-kv": { "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" - } - } - } + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true }, - "has-yarn": { + "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/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", "dev": true }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + }, + "is": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz", + "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==", + "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": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" + "kind-of": "^3.0.2" }, "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "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": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "is-buffer": "^1.1.5" } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", - "dev": true } } }, - "hash-sum": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", - "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==", + "is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", "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==", + "is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", "dev": true, "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" } }, - "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==", + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", "dev": true }, - "highlight.js": { - "version": "9.18.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.1.tgz", - "integrity": "sha512-OrVKYz70LHsnCgmbXctv/bfuvntIKDz177h0Co37DQ5jamGZLVmoCVMtjMtNZY3X9DrCcKfklHPNeA0uPZhSJg==", + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, - "hmac-drbg": { + "is-binary-path": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "binary-extensions": "^1.0.0" } }, - "hoopy": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", - "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "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=", + "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": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" + "ci-info": "^1.5.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-entities": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", - "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==", - "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==", + "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": { - "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 - } + "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" } }, - "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=", + "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": { - "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" + "kind-of": "^3.0.2" }, "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 - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "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" - } - }, - "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==", + "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": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" + "is-buffer": "^1.1.5" } } } }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true + }, + "is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true + }, + "is-deflate": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-deflate/-/is-deflate-1.0.0.tgz", + "integrity": "sha1-yGKQHDwWH7CdrHzcfnhPgOmPLxQ=", + "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": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" }, "dependencies": { - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "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 - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } } } }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "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 }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "is-docker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", "dev": true }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "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-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, + "is-get-set-prop": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz", + "integrity": "sha1-JzGHfk14pqae3M5rudaLB3nnYxI=", "dev": true, "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } + "get-set-props": "^0.1.0", + "lowercase-keys": "^1.0.0" } }, - "http-proxy": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", - "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==", + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" + "is-extglob": "^2.1.1" } }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "is-gzip": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-gzip/-/is-gzip-1.0.0.tgz", + "integrity": "sha1-bKiwe5nHeZgCWQDlVc7Y7YCHmoM=", + "dev": true + }, + "is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true + }, + "is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", "dev": true, "requires": { - "agent-base": "4", - "debug": "3.1.0" + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" }, "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", "dev": true } } }, - "http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", - "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", - "dev": true, - "requires": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "is-js-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-js-type/-/is-js-type-2.0.0.tgz", + "integrity": "sha1-c2FwBtZZtOtHKbunR9KHgt8PfiI=", "dev": true, "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "js-types": "^1.0.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=", + "is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", "dev": true }, - "https-proxy-agent": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz", - "integrity": "sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg==", + "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": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" + "kind-of": "^3.0.2" }, "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "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": { - "ms": "^2.1.1" + "is-buffer": "^1.1.5" } } } }, - "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "is-obj-prop": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-1.0.0.tgz", + "integrity": "sha1-s03nnEULjXxzqyzfZ9yHWtuF+A4=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0", + "obj-props": "^1.0.0" + } + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", "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==", + "is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", "dev": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "is-path-inside": "^2.1.0" } }, - "icss-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", - "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", + "is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", "dev": true, "requires": { - "postcss": "^7.0.14" + "path-is-inside": "^1.0.2" } }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "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": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", "dev": true }, - "import-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", - "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", + "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": { - "import-from": "^2.1.0" + "isobject": "^3.0.1" } }, - "import-fresh": { + "is-proto-prop": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "resolved": "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-2.0.0.tgz", + "integrity": "sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg==", "dev": true, "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" + "lowercase-keys": "^1.0.0", + "proto-props": "^2.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=", + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", "dev": true, "requires": { - "resolve-from": "^3.0.0" + "has-symbols": "^1.0.1" } }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "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 }, - "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==", + "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": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" + "html-comment-regex": "^1.1.0" } }, - "import-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-2.0.0.tgz", - "integrity": "sha512-iczM/v9drffdNnABOKwj0f9G3cFDon99VcG1mxeBsdqnbd+vnQ5c2uAiCHNQITqFTOPaEvwg3VjoWCur0uHLEw==", + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "is-whitespace": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-whitespace/-/is-whitespace-0.3.0.tgz", + "integrity": "sha1-Fjnssb4DauxppUy7QBz77XEUq38=", "dev": true }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "is-whitespace-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", + "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", "dev": true }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "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 }, - "infer-owner": { + "is-word-character": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", + "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", "dev": true }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "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-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "dev": true, + "requires": { + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "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" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", "dev": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "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 + } } }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "istanbul-reports": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", + "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0" + } }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "javascript-stringify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.0.1.tgz", + "integrity": "sha512-yV+gqbd5vaOYjqlbk16EG89xB5udgjqQF3C5FAORDg4f/IS1Yc5ERCv5e/57yBcfJYw05V5JyIXabhwb75Xxow==", "dev": true }, - "inquirer": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", - "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", + "jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz", + "integrity": "sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw==", "dev": true, "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", - "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.15", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.5.3", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" + "import-local": "^2.0.0", + "jest-cli": "^24.9.0" }, "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" } }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", "dev": true, "requires": { - "color-name": "~1.1.4" + "ci-info": "^2.0.0" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "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 }, - "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "jest-cli": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.9.0.tgz", + "integrity": "sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg==", "dev": true, "requires": { - "mimic-fn": "^2.1.0" + "@jest/core": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "import-local": "^2.0.0", + "is-ci": "^2.0.0", + "jest-config": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "prompts": "^2.0.1", + "realpath-native": "^1.1.0", + "yargs": "^13.3.0" } }, - "restore-cursor": { + "string-width": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" } }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "ansi-regex": "^4.1.0" } - } - } - }, - "internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", - "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", - "dev": true, - "requires": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" - }, - "dependencies": { - "default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", - "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "requires": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" } - } - } - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, - "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": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "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.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "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=", + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } }, - "is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", - "dev": true - }, - "is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "dev": true, - "requires": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - } - }, - "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", - "dev": true - }, - "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=", + "jest-changed-files": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.9.0.tgz", + "integrity": "sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg==", "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==", - "dev": true - }, - "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", - "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" + "@jest/types": "^24.9.0", + "execa": "^1.0.0", + "throat": "^4.0.0" + } + }, + "jest-config": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", + "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^24.9.0", + "@jest/types": "^24.9.0", + "babel-jest": "^24.9.0", + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^24.9.0", + "jest-environment-node": "^24.9.0", + "jest-get-type": "^24.9.0", + "jest-jasmine2": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "micromatch": "^3.1.10", + "pretty-format": "^24.9.0", + "realpath-native": "^1.1.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=", + "jest-diff": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz", + "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==", "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" - } - } + "chalk": "^2.0.1", + "diff-sequences": "^24.9.0", + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" } }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", - "dev": true - }, - "is-deflate": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-deflate/-/is-deflate-1.0.0.tgz", - "integrity": "sha1-yGKQHDwWH7CdrHzcfnhPgOmPLxQ=", - "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==", + "jest-docblock": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", + "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", "dev": true, "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "detect-newline": "^2.1.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==", + "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 } } }, - "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-docker": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", - "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", - "dev": true - }, - "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-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-get-set-prop": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz", - "integrity": "sha1-JzGHfk14pqae3M5rudaLB3nnYxI=", + "jest-each": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", + "integrity": "sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==", "dev": true, "requires": { - "get-set-props": "^0.1.0", - "lowercase-keys": "^1.0.0" + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "jest-get-type": "^24.9.0", + "jest-util": "^24.9.0", + "pretty-format": "^24.9.0" } }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "jest-environment-jsdom": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", + "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", "dev": true, "requires": { - "is-extglob": "^2.1.1" + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0", + "jsdom": "^11.5.1" } }, - "is-gzip": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-gzip/-/is-gzip-1.0.0.tgz", - "integrity": "sha1-bKiwe5nHeZgCWQDlVc7Y7YCHmoM=", - "dev": true - }, - "is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", - "dev": true - }, - "is-installed-globally": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", - "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "jest-environment-jsdom-fifteen": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom-fifteen/-/jest-environment-jsdom-fifteen-1.0.2.tgz", + "integrity": "sha512-nfrnAfwklE1872LIB31HcjM65cWTh1wzvMSp10IYtPJjLDUbTTvDpajZgIxUnhRmzGvogdHDayCIlerLK0OBBg==", "dev": true, "requires": { - "global-dirs": "^2.0.1", - "is-path-inside": "^3.0.1" + "@jest/environment": "^24.3.0", + "@jest/fake-timers": "^24.3.0", + "@jest/types": "^24.3.0", + "jest-mock": "^24.0.0", + "jest-util": "^24.0.0", + "jsdom": "^15.2.1" }, "dependencies": { - "is-path-inside": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", - "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "acorn": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", + "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", + "dev": true + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } + } + }, + "jsdom": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", + "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^7.1.0", + "acorn-globals": "^4.3.2", + "array-equal": "^1.0.0", + "cssom": "^0.4.1", + "cssstyle": "^2.0.0", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.1", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.2.0", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", + "saxes": "^3.1.9", + "symbol-tree": "^3.2.2", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^7.0.0", + "xml-name-validator": "^3.0.0" + } + }, + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "dev": true + }, + "tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "dev": true, + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "ws": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", + "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", "dev": true } } }, - "is-js-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-js-type/-/is-js-type-2.0.0.tgz", - "integrity": "sha1-c2FwBtZZtOtHKbunR9KHgt8PfiI=", + "jest-environment-node": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", + "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", "dev": true, "requires": { - "js-types": "^1.0.0" + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0" } }, - "is-npm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", - "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", + "jest-get-type": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", + "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", "dev": true }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "jest-haste-map": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", + "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==", "dev": true, "requires": { - "kind-of": "^3.0.2" + "@jest/types": "^24.9.0", + "anymatch": "^2.0.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.7", + "graceful-fs": "^4.1.15", + "invariant": "^2.2.4", + "jest-serializer": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.9.0", + "micromatch": "^3.1.10", + "sane": "^4.0.3", + "walker": "^1.0.7" }, "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, + "optional": true, "requires": { - "is-buffer": "^1.1.5" + "bindings": "^1.5.0", + "nan": "^2.12.1" } - } - } - }, - "is-obj-prop": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-1.0.0.tgz", - "integrity": "sha1-s03nnEULjXxzqyzfZ9yHWtuF+A4=", - "dev": true, - "requires": { - "lowercase-keys": "^1.0.0", - "obj-props": "^1.0.0" + }, + "jest-worker": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", + "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^6.1.0" + } + }, + "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" + } + } } }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "jest-jasmine2": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz", + "integrity": "sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw==", "dev": true, "requires": { - "is-path-inside": "^2.1.0" + "@babel/traverse": "^7.1.0", + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "co": "^4.6.0", + "expect": "^24.9.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "pretty-format": "^24.9.0", + "throat": "^4.0.0" } }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "jest-leak-detector": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz", + "integrity": "sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==", "dev": true, "requires": { - "path-is-inside": "^1.0.2" + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" } }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true - }, - "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==", + "jest-matcher-utils": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz", + "integrity": "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==", "dev": true, "requires": { - "isobject": "^3.0.1" + "chalk": "^2.0.1", + "jest-diff": "^24.9.0", + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" } }, - "is-proto-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-2.0.0.tgz", - "integrity": "sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg==", + "jest-message-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", + "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", "dev": true, "requires": { - "lowercase-keys": "^1.0.0", - "proto-props": "^2.0.0" + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" } }, - "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "jest-mock": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz", + "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==", "dev": true, "requires": { - "has": "^1.0.3" + "@jest/types": "^24.9.0" } }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", "dev": true }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "jest-regex-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz", + "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==", "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==", + "jest-resolve": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", + "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", "dev": true, "requires": { - "html-comment-regex": "^1.1.0" + "@jest/types": "^24.9.0", + "browser-resolve": "^1.11.3", + "chalk": "^2.0.1", + "jest-pnp-resolver": "^1.2.1", + "realpath-native": "^1.1.0" } }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "jest-resolve-dependencies": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz", + "integrity": "sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g==", "dev": true, "requires": { - "has-symbols": "^1.0.1" + "@jest/types": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-snapshot": "^24.9.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-whitespace-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", - "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", - "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 + "jest-runner": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.9.0.tgz", + "integrity": "sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.4.2", + "exit": "^0.1.2", + "graceful-fs": "^4.1.15", + "jest-config": "^24.9.0", + "jest-docblock": "^24.3.0", + "jest-haste-map": "^24.9.0", + "jest-jasmine2": "^24.9.0", + "jest-leak-detector": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-resolve": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.6.0", + "source-map-support": "^0.5.6", + "throat": "^4.0.0" + }, + "dependencies": { + "jest-worker": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", + "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^6.1.0" + } + }, + "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" + } + } + } }, - "is-word-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", - "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", - "dev": true + "jest-runtime": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.9.0.tgz", + "integrity": "sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/environment": "^24.9.0", + "@jest/source-map": "^24.3.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/yargs": "^13.0.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.1.15", + "jest-config": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "strip-bom": "^3.0.0", + "yargs": "^13.3.0" + }, + "dependencies": { + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "jest-serializer": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz", + "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==", "dev": true }, - "is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", - "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" + } }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "jest-snapshot": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.9.0.tgz", + "integrity": "sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "expect": "^24.9.0", + "jest-diff": "^24.9.0", + "jest-get-type": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-resolve": "^24.9.0", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^24.9.0", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } }, - "isexe": { + "jest-transform-stub": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "resolved": "https://registry.npmjs.org/jest-transform-stub/-/jest-transform-stub-2.0.0.tgz", + "integrity": "sha512-lspHaCRx/mBbnm3h4uMMS3R5aZzMwyNpNIJLXj4cEsV0mIUtS4IjYJLSoyjRCtnxb6RIGJ4NL2quZzfIeNhbkg==", "dev": true }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dev": true, + "requires": { + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.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 + } + } + }, + "jest-validate": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", + "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "camelcase": "^5.3.1", + "chalk": "^2.0.1", + "jest-get-type": "^24.9.0", + "leven": "^3.1.0", + "pretty-format": "^24.9.0" + } }, - "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 + "jest-watch-typeahead": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-0.4.2.tgz", + "integrity": "sha512-f7VpLebTdaXs81rg/oj4Vg/ObZy2QtGzAmGLNsqUS5G5KtSN68tFcIsbvNODfNyQxU78g7D8x77o3bgfBTR+2Q==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^2.4.1", + "jest-regex-util": "^24.9.0", + "jest-watcher": "^24.3.0", + "slash": "^3.0.0", + "string-length": "^3.1.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "string-length": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", + "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", + "dev": true, + "requires": { + "astral-regex": "^1.0.0", + "strip-ansi": "^5.2.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } }, - "javascript-stringify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.0.1.tgz", - "integrity": "sha512-yV+gqbd5vaOYjqlbk16EG89xB5udgjqQF3C5FAORDg4f/IS1Yc5ERCv5e/57yBcfJYw05V5JyIXabhwb75Xxow==", - "dev": true + "jest-watcher": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.9.0.tgz", + "integrity": "sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw==", + "dev": true, + "requires": { + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/yargs": "^13.0.0", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "jest-util": "^24.9.0", + "string-length": "^2.0.0" + }, + "dependencies": { + "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 + } + } }, "jest-worker": { "version": "25.5.0", @@ -8670,6 +13074,27 @@ } } }, + "js-beautify": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.12.0.tgz", + "integrity": "sha512-hZCm93+sWHqrsB2ac38cPX4A9t6mfReq13ZUr/0dk6rCXNLIq0R4lu0EiuJc0Ip6RiWNtE0vECjXOhcy/jMt9Q==", + "dev": true, + "requires": { + "config-chain": "^1.1.12", + "editorconfig": "^0.15.3", + "glob": "^7.1.3", + "mkdirp": "^1.0.4", + "nopt": "^4.0.3" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, "js-message": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.5.tgz", @@ -8713,6 +13138,63 @@ "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" + }, + "dependencies": { + "acorn": { + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "dev": true + }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, + "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" + } + } + } + }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -8720,11 +13202,24 @@ "dev": true }, "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, + "json-file-plus": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/json-file-plus/-/json-file-plus-3.3.1.tgz", + "integrity": "sha512-wo0q1UuiV5NsDPQDup1Km8IwEeqe+olr8tkWxeJq9Bjtcp7DZ0l+yrg28fSC3DEtrE311mhTZ54QGS6oiqnZEA==", + "dev": true, + "requires": { + "is": "^3.2.1", + "node.extend": "^2.0.0", + "object.assign": "^4.1.0", + "promiseback": "^2.0.2", + "safer-buffer": "^2.0.2" + } + }, "json-fixer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/json-fixer/-/json-fixer-1.4.1.tgz", @@ -8834,9 +13329,9 @@ } }, "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.3.0.tgz", + "integrity": "sha512-b0EBt8SWFNnixVdvoR2ZtEGa9ZqLhbJnOjezn+WP+8kspFm+PFYDN8Z4Bc7pRlDjvuVcADSUkroIuTWWn/YiIA==", "dev": true }, "jsonfile": { @@ -8873,12 +13368,12 @@ } }, "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.1.tgz", + "integrity": "sha512-xz6Jv6oNkbhrFCvCP7HQa8AaII8y8LRpoSm661NOKLr4uHuBwhX4epXrPQgF3+xdJnN4Esm5X0xwY4bOlALOtw==", "dev": true, "requires": { - "json-buffer": "3.0.0" + "json-buffer": "3.0.1" } }, "killable": { @@ -8893,6 +13388,18 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "klona": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/klona/-/klona-1.1.2.tgz", + "integrity": "sha512-xf88rTeHiXk+XE2Vhi6yj8Wm3gMZrygGdKjJqN8HkV+PwF/t50/LdAKHoHpPcxFAlmQszTZ1CugrK25S7qDRLA==", + "dev": true + }, "latest-version": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", @@ -8930,6 +13437,12 @@ "invert-kv": "^1.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": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -8991,6 +13504,36 @@ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.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" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, "loader-fs-cache": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz", @@ -9071,19 +13614,19 @@ } }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "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": "^2.0.0", + "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", "dev": true }, "lodash.assign": { @@ -9110,42 +13653,114 @@ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, + "lodash.constant": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash.constant/-/lodash.constant-3.0.0.tgz", + "integrity": "sha1-v+Bczn5RWzEokl1jYhOEIL1iSRA=", + "dev": true + }, "lodash.defaultsdeep": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz", "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==", "dev": true }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=", + "dev": true + }, + "lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=", + "dev": true + }, + "lodash.flatmap": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.flatmap/-/lodash.flatmap-4.5.0.tgz", + "integrity": "sha1-74y/QI9uSCaGYzRTBcaswLd4cC4=", + "dev": true + }, "lodash.flatten": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", "dev": true }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=", + "dev": true + }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, + "lodash.has": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz", + "integrity": "sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=", + "dev": true + }, + "lodash.isarray": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-4.0.0.tgz", + "integrity": "sha1-KspJayjEym1yZxUxNZDALm6jRAM=", + "dev": true + }, + "lodash.isempty": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", + "integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=", + "dev": true + }, "lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", "dev": true }, + "lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", + "dev": true + }, + "lodash.isundefined": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz", + "integrity": "sha1-I+89lTVWUgOmbO/VuDD4SJEa+0g=", + "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.keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-4.2.0.tgz", + "integrity": "sha1-oIYCrBLk+4P5H8H7ejYKTZujUgU=", + "dev": true + }, "lodash.last": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash.last/-/lodash.last-3.0.0.tgz", "integrity": "sha1-JC9mMRLdTG5jcoxgo8kJ0b2tvUw=", "dev": true }, + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", + "dev": true + }, "lodash.mapvalues": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", @@ -9158,30 +13773,66 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, + "lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=", + "dev": true + }, "lodash.set": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", "dev": true }, + "lodash.size": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.size/-/lodash.size-4.2.0.tgz", + "integrity": "sha1-cf517T6r2yvLc6GwtPUcOS7ie4Y=", + "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.sortedlastindex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/lodash.sortedlastindex/-/lodash.sortedlastindex-4.1.0.tgz", "integrity": "sha1-RWmHgZa0UNrGqrTOsIls7tSmclU=", "dev": true }, + "lodash.topairs": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.topairs/-/lodash.topairs-4.3.0.tgz", + "integrity": "sha1-O23qo31g+xFnE8RsXxfqGQ7EjWQ=", + "dev": true + }, "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.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", + "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 }, + "lodash.values": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-4.3.0.tgz", + "integrity": "sha1-o6bCsOvsxcLLocF+bmIP6BtT00c=", + "dev": true + }, "lodash.zip": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", @@ -9203,6 +13854,15 @@ "chalk": "^2.0.1" } }, + "logic-solver": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/logic-solver/-/logic-solver-2.0.1.tgz", + "integrity": "sha1-6fpHAC612M2nYW1BY5uXVS62dL4=", + "dev": true, + "requires": { + "underscore": "^1.7.0" + } + }, "loglevel": { "version": "1.6.8", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", @@ -9240,9 +13900,9 @@ } }, "macos-release": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.4.0.tgz", - "integrity": "sha512-ko6deozZYiAkqa/0gmcsz+p4jSy3gY7/ZsCEokPaYd8k+6/aXGkiTgr61+Owup7Sf+xjqW8u2ElhoM9SEcEfuA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.4.1.tgz", + "integrity": "sha512-H/QHeBIN1fIGJX517pvK8IEK53yQOW7YcEI55oYtgjDdoCQQz7eJS94qt5kNrscReEyuD/JcdFCm2XBEcGOITg==", "dev": true }, "make-dir": { @@ -9255,6 +13915,21 @@ "semver": "^5.6.0" } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "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-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -9379,12 +14054,20 @@ "requires": { "bn.js": "^4.0.0", "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "mime": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz", - "integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", "dev": true }, "mime-db": { @@ -9479,9 +14162,9 @@ "dev": true }, "minipass": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", - "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", "dev": true, "requires": { "yallist": "^4.0.0" @@ -9514,14 +14197,35 @@ } }, "minipass-pipeline": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.2.tgz", - "integrity": "sha512-3JS5A2DKhD2g0Gg8x3yamO0pj7YeKGwVlDS90pF++kxptwx/F+B//roxf9SqYil5tQo65bijy+dAuAFZmYOouA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", "dev": true, "requires": { "minipass": "^3.0.0" } }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "requires": { + "minipass": "^2.9.0" + }, + "dependencies": { + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } + } + }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", @@ -9793,9 +14497,9 @@ "dev": true }, "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, "netmask": { @@ -9819,12 +14523,42 @@ "lower-case": "^1.1.1" } }, + "node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "dev": true + }, + "node-cache": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-4.2.1.tgz", + "integrity": "sha512-BOb67bWg2dTyax5kdef5WfU3X8xu4wPg+zHzkvls0Q/QpYycIFRLEEIdAx9Wma43DxG6Qzn4illdZoYseKWa4A==", + "dev": true, + "requires": { + "clone": "2.x", + "lodash": "^4.17.15" + }, + "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.9.0", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", "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", @@ -9875,12 +14609,51 @@ } } }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-notifier": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", + "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", + "dev": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^1.1.0", + "semver": "^5.5.0", + "shellwords": "^0.1.1", + "which": "^1.3.0" + } + }, "node-releases": { - "version": "1.1.53", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.53.tgz", - "integrity": "sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ==", + "version": "1.1.60", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.60.tgz", + "integrity": "sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==", "dev": true }, + "node.extend": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-2.0.2.tgz", + "integrity": "sha512-pDT4Dchl94/+kkgdwyS2PauDFjZG0Hk0IcHIB+LkW27HLDtdoeMxHTxZh39DYbPP8UflWXWj9JcdDozF+YDOpQ==", + "dev": true, + "requires": { + "has": "^1.0.3", + "is": "^3.2.1" + } + }, + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -9934,6 +14707,29 @@ "boolbase": "~1.0.0" } }, + "null-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-3.0.0.tgz", + "integrity": "sha512-hf5sNLl8xdRho4UPBOOeoIwT3WhjYcMUQm0zj44EhD6UscMAz72o2udpoDFBgykucdEDGIcd6SXbc/G6zssbzw==", + "dev": true, + "requires": { + "loader-utils": "^1.2.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" + } + } + } + }, "num2fraction": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", @@ -9946,6 +14742,12 @@ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -10002,9 +14804,9 @@ "dev": true }, "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", "dev": true }, "object-is": { @@ -10192,6 +14994,12 @@ "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": "1.4.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", @@ -10217,12 +15025,31 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz", + "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==", "dev": true }, + "p-each-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", + "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=", + "dev": true, + "requires": { + "p-reduce": "^1.0.0" + } + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -10230,21 +15057,21 @@ "dev": true }, "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { - "p-try": "^1.0.0" + "p-try": "^2.0.0" } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "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": "^1.1.0" + "p-limit": "^2.0.0" } }, "p-map": { @@ -10256,6 +15083,12 @@ "aggregate-error": "^3.0.0" } }, + "p-reduce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", + "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=", + "dev": true + }, "p-retry": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", @@ -10266,9 +15099,9 @@ } }, "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "pac-proxy-agent": { @@ -10312,6 +15145,123 @@ "semver": "^6.2.0" }, "dependencies": { + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "dev": true + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -10364,14 +15314,13 @@ } }, "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", "dev": true, "requires": { - "asn1.js": "^4.0.0", + "asn1.js": "^5.2.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" @@ -10403,6 +15352,15 @@ "lines-and-columns": "^1.1.6" } }, + "parse-link-header": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-link-header/-/parse-link-header-1.0.1.tgz", + "integrity": "sha1-vt/g0hGK64S+deewJUGeyKYRQKc=", + "dev": true, + "requires": { + "xtend": "~4.0.1" + } + }, "parse5": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", @@ -10496,9 +15454,9 @@ } }, "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", "dev": true, "requires": { "create-hash": "^1.1.2", @@ -10558,6 +15516,15 @@ "pinkie": "^2.0.0" } }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, "pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", @@ -10565,61 +15532,19 @@ "dev": true, "requires": { "find-up": "^3.0.0" - }, - "dependencies": { - "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" - } - }, - "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" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "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-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - } } }, - "pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true + }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true }, "pnp-webpack-plugin": { "version": "1.6.4", @@ -10631,14 +15556,14 @@ } }, "portfinder": { - "version": "1.0.26", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.26.tgz", - "integrity": "sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==", + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", "dev": true, "requires": { "async": "^2.6.2", "debug": "^3.1.1", - "mkdirp": "^0.5.1" + "mkdirp": "^0.5.5" }, "dependencies": { "debug": { @@ -10687,9 +15612,9 @@ } }, "postcss-calc": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.2.tgz", - "integrity": "sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.3.tgz", + "integrity": "sha512-IB/EAEmZhIMEIhG7Ov4x+l47UaXOS1n2f4FBUk/aKllQhtSCxWhTzn0nJgkqN7fo/jcWySvWTSB6Syk9L+31bA==", "dev": true, "requires": { "postcss": "^7.0.27", @@ -10949,15 +15874,43 @@ } }, "postcss-modules-local-by-default": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz", - "integrity": "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", + "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", "dev": true, "requires": { "icss-utils": "^4.1.1", - "postcss": "^7.0.16", + "postcss": "^7.0.32", "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.0" + "postcss-value-parser": "^4.1.0" + }, + "dependencies": { + "postcss": { + "version": "7.0.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", + "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.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 + }, + "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-modules-scope": { @@ -11204,12 +16157,12 @@ } }, "postcss-scss": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.0.0.tgz", - "integrity": "sha512-um9zdGKaDZirMm+kZFKKVsnKPF7zF7qBAtIfTSnZXD1jZ0JNZIxdB6TxQOjCnlSzLRInVl2v3YdBh/M881C4ug==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz", + "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==", "dev": true, "requires": { - "postcss": "^7.0.0" + "postcss": "^7.0.6" } }, "postcss-selector-parser": { @@ -11224,9 +16177,9 @@ } }, "postcss-styl": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/postcss-styl/-/postcss-styl-0.7.1.tgz", - "integrity": "sha512-9OvnmX9iJv3u2AR6FrHskq5LGkQk/Mist/BJKjopNF0ercOtfYJz3ntBw/w3p3vI/UyZVrxOsLSXn0anqulNpw==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/postcss-styl/-/postcss-styl-0.7.2.tgz", + "integrity": "sha512-e+k6Gs3EMxjDQRyYg1+Xg/k8Zk9RvsOC1R4DRK905xb7mEVgHg23+v72XvKb7jQ8rhRm1TCF51Bk1OBDVDJPGg==", "dev": true, "requires": { "debug": "^4.1.1", @@ -11306,6 +16259,34 @@ "integrity": "sha512-flbKuLB7ftrW2zQYJjb0mF6zY7R0jDrYatpr0BBNj04Eb+g1RLbquOQSJE1LffDZfzU03fwJQ74grqQjQjYa3Q==", "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": "5.3.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz", + "integrity": "sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==", + "dev": true + }, "pretty-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", @@ -11316,11 +16297,17 @@ "utila": "~0.4" } }, - "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 + "pretty-format": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + } }, "process": { "version": "0.11.10", @@ -11346,13 +16333,48 @@ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", "dev": true, "requires": { - "asap": "~2.0.3" + "asap": "~2.0.3" + } + }, + "promise-deferred": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/promise-deferred/-/promise-deferred-2.0.3.tgz", + "integrity": "sha512-n10XaoznCzLfyPFOlEE8iurezHpxrYzyjgq/1eW9Wk1gJwur/N7BdBmjJYJpqMeMcXK4wEbzo2EvZQcqjYcKUQ==", + "dev": true, + "requires": { + "promise": "^7.3.1" + } + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "promiseback": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/promiseback/-/promiseback-2.0.3.tgz", + "integrity": "sha512-VZXdCwS0ppVNTIRfNsCvVwJAaP2b+pxQF7lM8DMWfmpNWyTxB6O5YNbzs+8z0ki/KIBHKHk308NTIl4kJUem3w==", + "dev": true, + "requires": { + "is-callable": "^1.1.5", + "promise-deferred": "^2.0.3" + } + }, + "prompts": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", + "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.4" } }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "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 }, "proto-props": { @@ -11423,6 +16445,14 @@ "parse-asn1": "^5.0.0", "randombytes": "^2.0.1", "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "pump": { @@ -11508,15 +16538,21 @@ "dev": true }, "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "dev": true }, "ramda": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.0.tgz", - "integrity": "sha512-pVzZdDpWwWqEVVLshWUHjNwuVP7SfcmPraYuqocJp1yo2U1R7P+5QAfDhdItkuoGqIBnBYrtPp7rEPqDn9HlZA==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", + "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==", "dev": true }, "randombytes": { @@ -11576,6 +16612,12 @@ } } }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -11682,6 +16724,15 @@ "readable-stream": "^2.0.2" } }, + "realpath-native": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz", + "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==", + "dev": true, + "requires": { + "util.promisify": "^1.0.0" + } + }, "rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", @@ -11697,9 +16748,9 @@ "integrity": "sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng==" }, "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", + "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==", "dev": true }, "regenerate-unicode-properties": { @@ -11718,13 +16769,12 @@ "dev": true }, "regenerator-transform": { - "version": "0.14.4", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.4.tgz", - "integrity": "sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==", + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", + "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", "dev": true, "requires": { - "@babel/runtime": "^7.8.4", - "private": "^0.1.8" + "@babel/runtime": "^7.8.4" } }, "regex-not": { @@ -11754,9 +16804,9 @@ } }, "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", "dev": true }, "regexpu-core": { @@ -11774,9 +16824,9 @@ } }, "registry-auth-token": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.1.1.tgz", - "integrity": "sha512-9bKS7nTl9+/A1s7tnPeGrUpRcVY+LUh7bfFgzpndALdPfXQBfQV77rQVtqgUV3ti4vc/Ik81Ex8UJDWDQ12zQA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz", + "integrity": "sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w==", "dev": true, "requires": { "rc": "^1.2.8" @@ -11792,9 +16842,9 @@ } }, "regjsgen": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", - "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", "dev": true }, "regjsparser": { @@ -11954,21 +17004,21 @@ } }, "request-promise-core": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", - "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", "dev": true, "requires": { - "lodash": "^4.17.15" + "lodash": "^4.17.19" } }, "request-promise-native": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", - "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", "dev": true, "requires": { - "request-promise-core": "1.1.3", + "request-promise-core": "1.1.4", "stealthy-require": "^1.1.1", "tough-cookie": "^2.3.3" } @@ -12012,6 +17062,12 @@ "path-parse": "^1.0.6" } }, + "resolve-alpn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz", + "integrity": "sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA==", + "dev": true + }, "resolve-cwd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", @@ -12034,12 +17090,20 @@ "dev": true }, "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", + "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", "dev": true, "requires": { - "lowercase-keys": "^1.0.0" + "lowercase-keys": "^2.0.0" + }, + "dependencies": { + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } } }, "restore-cursor": { @@ -12101,6 +17165,12 @@ "inherits": "^2.0.1" } }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true + }, "run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -12123,9 +17193,9 @@ } }, "rxjs": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", - "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", + "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -12152,32 +17222,71 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "dev": true, + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + } + }, "sass": { - "version": "1.26.9", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.26.9.tgz", - "integrity": "sha512-t8AkRVi+xvba4yZiLWkJdgJHBFCB3Dh4johniQkPy9ywkgFHNasXFEFP+RG/F6LhQ+aoE4aX+IorIWQjS0esVw==", + "version": "1.26.10", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.26.10.tgz", + "integrity": "sha512-bzN0uvmzfsTvjz0qwccN1sPm2HxxpNI/Xa+7PlUEMS+nQvbyuEK7Y0qFqxlPHhiNHb1Ze8WQJtU31olMObkAMw==", "dev": true, "requires": { "chokidar": ">=2.0.0 <4.0.0" } }, "sass-loader": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", - "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-9.0.3.tgz", + "integrity": "sha512-fOwsP98ac1VMme+V3+o0HaaMHp8Q/C9P+MUazLFVi3Jl7ORGHQXL1XeRZt3zLSGZQQPC8xE42Y2WptItvGjDQg==", "dev": true, "requires": { - "clone-deep": "^4.0.1", - "loader-utils": "^1.2.3", - "neo-async": "^2.6.1", - "schema-utils": "^2.6.1", - "semver": "^6.3.0" + "klona": "^1.1.2", + "loader-utils": "^2.0.0", + "neo-async": "^2.6.2", + "schema-utils": "^2.7.0", + "semver": "^7.3.2" }, "dependencies": { + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + } + }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true } } @@ -12188,6 +17297,15 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, + "saxes": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "dev": true, + "requires": { + "xmlchars": "^2.1.1" + } + }, "schema-utils": { "version": "2.6.6", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.6.tgz", @@ -12295,10 +17413,13 @@ } }, "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } }, "serve-index": { "version": "1.9.1", @@ -12425,15 +17546,6 @@ "safe-buffer": "^5.0.1" } }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -12466,6 +17578,18 @@ "rechoir": "^0.6.2" } }, + "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.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", @@ -12489,6 +17613,12 @@ } } }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", @@ -12643,19 +17773,19 @@ } }, "snyk": { - "version": "1.355.0", - "resolved": "https://registry.npmjs.org/snyk/-/snyk-1.355.0.tgz", - "integrity": "sha512-U/SiFq2QisMmKAn/zYHbx1aZNyJpc0160gU8ywlqkcAOsVDCQkGxiCU89f3bl9Bzx3wg8HAnXz0OVmYoYxVCYg==", + "version": "1.381.1", + "resolved": "https://registry.npmjs.org/snyk/-/snyk-1.381.1.tgz", + "integrity": "sha512-CSTBkUNYaOZgaXnFOxsQsHT9x0Wifsg4Fm0ahceliEhjRuKTFkOBTt/TTtRjXlHZ+/DZ9uDRivYxomJaSlgpMQ==", "dev": true, "requires": { - "@snyk/cli-interface": "2.8.0", - "@snyk/dep-graph": "1.18.3", + "@snyk/cli-interface": "2.8.1", + "@snyk/dep-graph": "1.19.3", "@snyk/gemfile": "1.2.0", "@snyk/graphlib": "2.1.9-patch", "@snyk/inquirer": "6.2.2-patch", "@snyk/lodash": "^4.17.15-patch", "@snyk/ruby-semver": "2.2.0", - "@snyk/snyk-cocoapods-plugin": "2.3.0", + "@snyk/snyk-cocoapods-plugin": "2.5.0", "abbrev": "^1.1.1", "ansi-escapes": "3.2.0", "chalk": "^2.4.2", @@ -12671,12 +17801,13 @@ "proxy-from-env": "^1.0.0", "semver": "^6.0.0", "snyk-config": "3.1.0", - "snyk-docker-plugin": "3.12.3", - "snyk-go-plugin": "1.14.2", + "snyk-cpp-plugin": "1.2.0", + "snyk-docker-plugin": "3.17.0", + "snyk-go-plugin": "1.16.0", "snyk-gradle-plugin": "3.5.1", "snyk-module": "3.1.0", - "snyk-mvn-plugin": "2.17.1", - "snyk-nodejs-lockfile-parser": "1.22.0", + "snyk-mvn-plugin": "2.19.1", + "snyk-nodejs-lockfile-parser": "1.26.3", "snyk-nuget-plugin": "1.18.1", "snyk-php-plugin": "1.9.0", "snyk-policy": "1.14.1", @@ -12722,9 +17853,9 @@ } }, "open": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/open/-/open-7.0.4.tgz", - "integrity": "sha512-brSA+/yq+b08Hsr4c8fsEW2CRzk1BmfN3SAK/5VCHQ9bdoZJ4qa/+AfR0xHjlbbZUyPkUHs1b8x1RqdyZdkVqQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-7.2.0.tgz", + "integrity": "sha512-4HeyhxCvBTI5uBePsAdi55C5fmqnWZ2e2MlmvWi5KW5tdH5rxoiv/aMtbeVxKZc3eWkT1GymMnLG8XC4Rq4TDQ==", "dev": true, "requires": { "is-docker": "^2.0.0", @@ -12781,29 +17912,120 @@ "nconf": "^0.10.0" } }, + "snyk-cpp-plugin": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/snyk-cpp-plugin/-/snyk-cpp-plugin-1.2.0.tgz", + "integrity": "sha512-zc2h0IAAjcxJwxWp4rauliwEUXZahmC3WoCgjTmRi36UhzwlxWJf8QpIeSOKJnc3t0NhlKzUc1YFkaQGJ2dXVQ==", + "dev": true, + "requires": { + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz", + "integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==", + "dev": true + } + } + }, "snyk-docker-plugin": { - "version": "3.12.3", - "resolved": "https://registry.npmjs.org/snyk-docker-plugin/-/snyk-docker-plugin-3.12.3.tgz", - "integrity": "sha512-Ysv7ZDvXFt6K11f1m6wJaqYS3yM7c8YhzOIPoEmrYZW+4tL+Al5DiyKaAQBudbfYEA7xa6S6qGqE3QRitHZ5nQ==", + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/snyk-docker-plugin/-/snyk-docker-plugin-3.17.0.tgz", + "integrity": "sha512-Pq0xr/NQQUss3bLb0rTfVtsot/9ID6TzZCWlF9nMrj9JFrJRrJPQxi/KO/uqfX0Nbwz4VysXDzwdWNtrxpaabg==", "dev": true, "requires": { "@snyk/rpm-parser": "^2.0.0", + "@snyk/snyk-docker-pull": "^3.2.0", "debug": "^4.1.1", "docker-modem": "2.1.3", "dockerfile-ast": "0.0.19", - "event-loop-spinner": "^1.1.0", + "event-loop-spinner": "^2.0.0", "gunzip-maybe": "^1.4.2", + "mkdirp": "^1.0.4", "semver": "^6.1.0", "snyk-nodejs-lockfile-parser": "1.22.0", "tar-stream": "^2.1.0", - "tslib": "^1" + "tmp": "^0.2.1", + "tslib": "^1", + "uuid": "^8.2.0" }, "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true + }, + "snyk-nodejs-lockfile-parser": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/snyk-nodejs-lockfile-parser/-/snyk-nodejs-lockfile-parser-1.22.0.tgz", + "integrity": "sha512-l6jLoJxqcIIkQopSdQuAstXdMw5AIgLu+uGc5CYpHyw8fYqOwna8rawwofNeGuwJAAv4nEiNiexeYaR88OCq6Q==", + "dev": true, + "requires": { + "@snyk/graphlib": "2.1.9-patch", + "@snyk/lodash": "^4.17.15-patch", + "@yarnpkg/lockfile": "^1.0.2", + "event-loop-spinner": "^1.1.0", + "p-map": "2.1.0", + "snyk-config": "^3.0.0", + "source-map-support": "^0.5.7", + "tslib": "^1.9.3", + "uuid": "^3.3.2" + }, + "dependencies": { + "event-loop-spinner": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/event-loop-spinner/-/event-loop-spinner-1.1.0.tgz", + "integrity": "sha512-YVFs6dPpZIgH665kKckDktEVvSBccSYJmoZUfhNUdv5d3Xv+Q+SKF4Xis1jolq9aBzuW1ZZhQh/m/zU/TPdDhw==", + "dev": true, + "requires": { + "tslib": "^1.10.0" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "requires": { + "rimraf": "^3.0.0" + } + }, + "uuid": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", + "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", + "dev": true } } }, @@ -12818,25 +18040,35 @@ } }, "snyk-go-plugin": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/snyk-go-plugin/-/snyk-go-plugin-1.14.2.tgz", - "integrity": "sha512-r/uaM3gk/RF7m/VGYswxlnA6I+kMgK3eVPsPyf7400BhqF8noh8K7v10CEg67mHA4JM0l7dZASqejr/5kKw9ZQ==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/snyk-go-plugin/-/snyk-go-plugin-1.16.0.tgz", + "integrity": "sha512-XNGHEFyP+pCzcqmXnj5T/1Oy6AZzm2WkTSuUpohWQ/09ecMRCCv2yrr/kwMQemrKN4+7CoJS/9xfm3GnNlzVHA==", "dev": true, "requires": { + "@snyk/dep-graph": "1.19.3", "@snyk/graphlib": "2.1.9-patch", "debug": "^4.1.1", "snyk-go-parser": "1.4.1", - "tmp": "0.1.0", + "tmp": "0.2.0", "tslib": "^1.10.0" }, "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, "tmp": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", - "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.0.tgz", + "integrity": "sha512-spsb5g6EiPmteS5TcOAECU3rltCMDMp4VMU2Sb0+WttN4qGobEkMAd+dkr1cubscN08JGNDX765dPbGImbG7MQ==", "dev": true, "requires": { - "rimraf": "^2.6.3" + "rimraf": "^3.0.0" } } } @@ -12856,6 +18088,47 @@ "tslib": "^2.0.0" }, "dependencies": { + "@snyk/cli-interface": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.8.0.tgz", + "integrity": "sha512-St/G39iJG1zQK15L24kcVYM2gmFc/ylBCcBqU2DMZKJKwOPccKLUO6s+dWIUXMccQ+DFS6TuHPvuAKQNi9C4Yg==", + "dev": true, + "requires": { + "@snyk/dep-graph": "1.19.0", + "@snyk/graphlib": "2.1.9-patch", + "tslib": "^1.9.3" + }, + "dependencies": { + "@snyk/dep-graph": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@snyk/dep-graph/-/dep-graph-1.19.0.tgz", + "integrity": "sha512-/0phOICMk4hkX2KtZgi+4KNd5G9oYDIlxQDQk+ui2xl4gonPvK6Q5MFzHP7Xet1YY/XoU33ox41i+IO48qZ+zQ==", + "dev": true, + "requires": { + "@snyk/graphlib": "2.1.9-patch", + "lodash.isequal": "^4.5.0", + "object-hash": "^2.0.3", + "semver": "^6.0.0", + "source-map-support": "^0.5.19", + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz", + "integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==", + "dev": true + } + } + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + } + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -12897,6 +18170,12 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "object-hash": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.0.3.tgz", + "integrity": "sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg==", + "dev": true + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -12906,6 +18185,12 @@ "glob": "^7.1.3" } }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", @@ -12925,9 +18210,9 @@ } }, "tslib": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", - "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz", + "integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==", "dev": true } } @@ -12943,39 +18228,45 @@ }, "dependencies": { "hosted-git-info": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.4.tgz", - "integrity": "sha512-4oT62d2jwSDBbLLFLZE+1vPuQ1h8p9wjrJ8Mqx5TjsyWmBMV5B13eJqn8pvluqubLf3cJPTfiYCIwNwDNmzScQ==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.5.tgz", + "integrity": "sha512-i4dpK6xj9BIpVOTboXIlKG9+8HMKggcrMX7WA24xZtKwX0TPelq/rbaS5rCKeNX8sJXZJGdSxpnEGtta+wismQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { - "lru-cache": "^5.1.1" + "yallist": "^4.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, "snyk-mvn-plugin": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/snyk-mvn-plugin/-/snyk-mvn-plugin-2.17.1.tgz", - "integrity": "sha512-U7ZKrKVnUW2gcyYIzvc0w9nRYh4NXv+wShTIcs++ARCAJOG9A4nxh+ZRmINQ7Sy7EB2qLIRwN4Ssr17+y2mhuA==", + "version": "2.19.1", + "resolved": "https://registry.npmjs.org/snyk-mvn-plugin/-/snyk-mvn-plugin-2.19.1.tgz", + "integrity": "sha512-VXYJSdhUmOQAyxdsv5frAKbi3UOcHPabWEQxQ9wxhVBEEmx2lP5ajv1a+ntxwWwL7u3jdc+rnCIKHpLlQJ5nyw==", "dev": true, "requires": { - "@snyk/cli-interface": "2.5.0", - "@snyk/java-call-graph-builder": "1.10.0", + "@snyk/cli-interface": "2.8.1", + "@snyk/java-call-graph-builder": "1.13.1", "debug": "^4.1.1", "needle": "^2.5.0", "tmp": "^0.1.0", "tslib": "1.11.1" }, "dependencies": { - "@snyk/cli-interface": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.5.0.tgz", - "integrity": "sha512-XMc2SCFH4RBSncZgoPb+BBlNq0NYpEpCzptKi69qyMpBy0VsRqIQqddedaazMCU1xEpXTytq6KMYpzUafZzp5Q==", - "dev": true, - "requires": { - "tslib": "^1.9.3" - } - }, "tmp": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", @@ -12988,20 +18279,26 @@ } }, "snyk-nodejs-lockfile-parser": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/snyk-nodejs-lockfile-parser/-/snyk-nodejs-lockfile-parser-1.22.0.tgz", - "integrity": "sha512-l6jLoJxqcIIkQopSdQuAstXdMw5AIgLu+uGc5CYpHyw8fYqOwna8rawwofNeGuwJAAv4nEiNiexeYaR88OCq6Q==", + "version": "1.26.3", + "resolved": "https://registry.npmjs.org/snyk-nodejs-lockfile-parser/-/snyk-nodejs-lockfile-parser-1.26.3.tgz", + "integrity": "sha512-mBQ6vhnXAeyMxlnl9amjJWpA+/3qqXwM8Sj/P+9uH2TByOFLxdGzMNQFcl3q/H2yUdcs/epVdXJp09A2dK2glA==", "dev": true, "requires": { "@snyk/graphlib": "2.1.9-patch", - "@snyk/lodash": "^4.17.15-patch", - "@yarnpkg/lockfile": "^1.0.2", - "event-loop-spinner": "^1.1.0", + "@yarnpkg/core": "^2.0.0-rc.29", + "@yarnpkg/lockfile": "^1.1.0", + "event-loop-spinner": "^2.0.0", + "lodash.clonedeep": "^4.5.0", + "lodash.flatmap": "^4.5.0", + "lodash.isempty": "^4.4.0", + "lodash.set": "^4.3.2", + "lodash.topairs": "^4.3.0", "p-map": "2.1.0", "snyk-config": "^3.0.0", "source-map-support": "^0.5.7", "tslib": "^1.9.3", - "uuid": "^3.3.2" + "uuid": "^3.3.2", + "yaml": "^1.9.2" }, "dependencies": { "p-map": { @@ -13737,10 +19034,16 @@ "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.1.1", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.1.1.tgz", - "integrity": "sha512-0PlYhdKh6AfFxRyK/v+6/k+/mMfyiEBbTM5L94D0ZytQnJ166wuwoTYLHFWGbs2dpA8Rgq763KGWmN1EQEYHRQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", + "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==", "dev": true }, "state-toggle": { @@ -13792,6 +19095,12 @@ "readable-stream": "^2.0.2" } }, + "stream-buffers": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.2.tgz", + "integrity": "sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==", + "dev": true + }, "stream-each": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", @@ -13815,12 +19124,52 @@ "xtend": "^4.0.0" } }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "stream-to-array": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz", + "integrity": "sha1-u/azn19D7DC8cbq8s3VXrOzzQ1M=", + "dev": true, + "requires": { + "any-promise": "^1.1.0" + } + }, + "stream-to-promise": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stream-to-promise/-/stream-to-promise-2.2.0.tgz", + "integrity": "sha1-se2y4cjLESidG1A8CNPyrvUeZQ8=", + "dev": true, + "requires": { + "any-promise": "~1.3.0", + "end-of-stream": "~1.1.0", + "stream-to-array": "~2.3.0" + }, + "dependencies": { + "end-of-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz", + "integrity": "sha1-6TUyWLqpEIll78QcsO+K3i88+wc=", + "dev": true, + "requires": { + "once": "~1.3.0" + } + }, + "once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "dev": true, + "requires": { + "wrappy": "1" + } + } + } + }, "streamsearch": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", @@ -13833,6 +19182,33 @@ "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", "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" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "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" + } + } + } + }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", @@ -13854,28 +19230,6 @@ "es-abstract": "^1.17.5" } }, - "string.prototype.trimleft": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", - "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimstart": "^1.0.0" - } - }, - "string.prototype.trimright": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", - "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "string.prototype.trimend": "^1.0.0" - } - }, "string.prototype.trimstart": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", @@ -13912,6 +19266,12 @@ } } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -13931,9 +19291,9 @@ "dev": true }, "strip-json-comments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", - "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "stylehacks": { @@ -13961,18 +19321,18 @@ } }, "stylus": { - "version": "0.54.7", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.7.tgz", - "integrity": "sha512-Yw3WMTzVwevT6ZTrLCYNHAFmanMxdylelL3hkWNgPMeTCpMwpV3nXjpOHuBXtFv7aiO2xRuQS6OoAdgkNcSNug==", + "version": "0.54.8", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.8.tgz", + "integrity": "sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg==", "dev": true, "requires": { "css-parse": "~2.0.0", "debug": "~3.1.0", - "glob": "^7.1.3", - "mkdirp": "~0.5.x", + "glob": "^7.1.6", + "mkdirp": "~1.0.4", "safer-buffer": "^2.1.2", "sax": "~1.2.4", - "semver": "^6.0.0", + "semver": "^6.3.0", "source-map": "^0.7.3" }, "dependencies": { @@ -13985,6 +19345,12 @@ "ms": "2.0.0" } }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -14041,6 +19407,12 @@ "util.promisify": "~1.0.0" } }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, "table": { "version": "5.4.6", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", @@ -14093,10 +19465,46 @@ "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", "dev": true }, + "tar": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "dependencies": { + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } + } + }, "tar-stream": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", - "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.3.tgz", + "integrity": "sha512-Z9yri56Dih8IaK8gncVPx4Wqt86NDmQTSh49XLZgjWpGZL9GK9HKParS2scqHCC4w6X9Gh2jwaU45V47XTKwVA==", "dev": true, "requires": { "bl": "^4.0.1", @@ -14150,9 +19558,9 @@ "dev": true }, "terser": { - "version": "4.6.13", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz", - "integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", + "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", "dev": true, "requires": { "commander": "^2.20.0", @@ -14169,16 +19577,16 @@ } }, "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", "dev": true, "requires": { "cacache": "^12.0.2", "find-cache-dir": "^2.1.0", "is-wsl": "^1.1.0", "schema-utils": "^1.0.0", - "serialize-javascript": "^2.1.2", + "serialize-javascript": "^4.0.0", "source-map": "^0.6.1", "terser": "^4.1.2", "webpack-sources": "^1.4.0", @@ -14204,6 +19612,41 @@ } } }, + "test-exclude": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", + "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", + "dev": true, + "requires": { + "glob": "^7.1.3", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^2.0.0" + }, + "dependencies": { + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + } + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -14220,9 +19663,9 @@ } }, "thenify": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", - "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", "dev": true, "requires": { "any-promise": "^1.0.0" @@ -14248,6 +19691,12 @@ "neo-async": "^2.6.0" } }, + "throat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", + "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", + "dev": true + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -14300,6 +19749,12 @@ "os-tmpdir": "~1.0.2" } }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", @@ -14388,6 +19843,15 @@ "punycode": "^2.1.1" } }, + "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" + } + }, "tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -14418,24 +19882,94 @@ "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", "dev": true }, + "ts-jest": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-24.3.0.tgz", + "integrity": "sha512-Hb94C/+QRIgjVZlJyiWwouYUF+siNJHJHknyspaOcZ+OQAIdFG/UrdQVXw/0B8Z3No34xkUXZJpOTy9alOWdVQ==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "json5": "2.x", + "lodash.memoize": "4.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-pnp": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==", "dev": true }, + "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-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 + } + } + }, "tslib": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", "dev": true }, + "tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "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": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "dev": true + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -14521,6 +20055,12 @@ } } }, + "underscore": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz", + "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg==", + "dev": true + }, "unherit": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", @@ -14728,9 +20268,9 @@ "dev": true }, "update-notifier": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.0.tgz", - "integrity": "sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.1.tgz", + "integrity": "sha512-9y+Kds0+LoLG6yN802wVXoIfxYEwh3FlZwzMwpCZp62S2i1/Jzeqb9Eeeju3NSHccGGasfGlK5/vEHbAifYRDg==", "dev": true, "requires": { "boxen": "^4.2.0", @@ -14952,9 +20492,9 @@ "dev": true }, "v8-compile-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", - "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", + "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", "dev": true }, "validate-npm-package-license": { @@ -15061,16 +20601,17 @@ "dev": true }, "vue": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.11.tgz", - "integrity": "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==" + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.12.tgz", + "integrity": "sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg==" }, "vue-cli-plugin-vuetify": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/vue-cli-plugin-vuetify/-/vue-cli-plugin-vuetify-2.0.6.tgz", - "integrity": "sha512-Y0VEK7gJTPW+LcSXBO8bx0YWzMoKMYHqcLpGF1EomGfAQrZafSulCZXcqF6++H4cPjFRkqB/YJ2xN/rTiu0DeA==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/vue-cli-plugin-vuetify/-/vue-cli-plugin-vuetify-2.0.7.tgz", + "integrity": "sha512-4riK5bzyvkZ4CxpQk/Vl6z8n8tmJUhuxh+k8xc/MZRdCt9RxAm3G4SxcEweroqKGXg+CRRfhqysaEQVtd4D40Q==", "dev": true, "requires": { + "null-loader": "^3.0.0", "semver": "^7.1.2", "shelljs": "^0.8.3" }, @@ -15084,62 +20625,161 @@ } }, "vue-eslint-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.0.0.tgz", - "integrity": "sha512-yR0dLxsTT7JfD2YQo9BhnQ6bUTLsZouuzt9SKRP7XNaZJV459gvlsJo4vT2nhZ/2dH9j3c53bIx9dnqU2prM9g==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.1.0.tgz", + "integrity": "sha512-Kr21uPfthDc63nDl27AGQEhtt9VrZ9nkYk/NTftJ2ws9XiJwzJJCnCr3AITQ2jpRMA0XPGDECxYH8E027qMK9Q==", "dev": true, "requires": { "debug": "^4.1.1", "eslint-scope": "^5.0.0", "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", + "espree": "^6.2.1", "esquery": "^1.0.1", "lodash": "^4.17.15" }, "dependencies": { "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + } + } + }, + "vue-hot-reload-api": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", + "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==", + "dev": true + }, + "vue-jest": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/vue-jest/-/vue-jest-3.0.6.tgz", + "integrity": "sha512-VyuM8wR0vAlYCbPRY+PhIqRU5yUyBnUmwYTo4IFScs2+tiuis5VBItU0PGC8Wcx6qJwKB5jq5p7WFhabzMFMgQ==", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0", + "chalk": "^2.1.0", + "deasync": "^0.1.15", + "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.9.3", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.3.tgz", + "integrity": "sha512-Y67VnGGgVLH5Voostx8JBZgPQTlDQeOVBLOEsjc2cXbCYBKexSKEpOA56x0YZofoDOTszrLnIShyOX1p9uCEHA==", + "dev": true, + "requires": { + "@vue/component-compiler-utils": "^3.1.0", + "hash-sum": "^1.0.2", + "loader-utils": "^1.1.0", + "vue-hot-reload-api": "^2.3.0", + "vue-style-loader": "^4.1.0" + }, + "dependencies": { + "hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", + "dev": true + } + } + }, + "vue-loader-v16": { + "version": "npm:vue-loader@16.0.0-beta.5", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.0.0-beta.5.tgz", + "integrity": "sha512-ciWfzNefqWlmzKznCWY9hl+fPP4KlQ0A9MtHbJ/8DpyY+dAM8gDrjufIdxwTgC4szE4EZC3A6ip/BbrqM84GqA==", + "dev": true, + "optional": true, + "requires": { + "@types/mini-css-extract-plugin": "^0.9.1", + "chalk": "^3.0.0", + "hash-sum": "^2.0.0", + "loader-utils": "^1.2.3", + "merge-source-map": "^1.1.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "optional": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "optional": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "optional": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": 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 + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", "dev": true, + "optional": true, "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "has-flag": "^4.0.0" } } } }, - "vue-hot-reload-api": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", - "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==", - "dev": true - }, - "vue-loader": { - "version": "15.9.2", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.2.tgz", - "integrity": "sha512-oXBubaY//CYEISBlHX+c2YPJbmOH68xXPXjFv4MAgPqQvUsnjrBAjCJi8HXZ/r/yfn0tPL5VZj1Zcp8mJPI8VA==", - "dev": true, - "requires": { - "@vue/component-compiler-utils": "^3.1.0", - "hash-sum": "^1.0.2", - "loader-utils": "^1.1.0", - "vue-hot-reload-api": "^2.3.0", - "vue-style-loader": "^4.1.0" - }, - "dependencies": { - "hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", - "dev": true - } - } - }, "vue-router": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.3.4.tgz", - "integrity": "sha512-SdKRBeoXUjaZ9R/8AyxsdTqkOfMcI5tWxPZOUX5Ie1BTL5rPSZ0O++pbiZCeYeythiZIdLEfkDiQPKIaWk5hDg==" + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.4.3.tgz", + "integrity": "sha512-BADg1mjGWX18Dpmy6bOGzGNnk7B/ZA0RxuA6qedY/YJwirMfKXIDzcccmHbQI0A6k5PzMdMloc0ElHfyOoX35A==" }, "vue-style-loader": { "version": "4.1.2", @@ -15160,9 +20800,9 @@ } }, "vue-template-compiler": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz", - "integrity": "sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA==", + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.12.tgz", + "integrity": "sha512-OzzZ52zS41YUbkCBfdXShQTe69j1gQDZ9HIX8miuC9C3rBCk9wIRjLiZZLrmX9V+Ftq/YEyv1JaVr5Y/hNtByg==", "dev": true, "requires": { "de-indent": "^1.0.2", @@ -15181,14 +20821,14 @@ "integrity": "sha512-/sL1slXSxbFkrk9acgRSbykwcs7EmdTVxDcmdb5WHmpQG9cFb//LTaJy4EiH/e58nnD6ZHw2B5k+Gz0mTaQszA==" }, "vuetify": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-2.3.3.tgz", - "integrity": "sha512-N9Rwx/cscIdHfBItHxiwkhmoxIVyZLBRWd/5LJJs4aVZIX6qkjQV6ThhxzqCYgFDb2jKMftavWX5hNQTxA9qEA==" + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-2.3.9.tgz", + "integrity": "sha512-E5K9flTvS21tCkHgqDBMl0BY/Rld4SLUaJpQ+sQdL8/2uPcWmWLrdumn4SI8LBFojE0UP1GSaH4zKuxLL36fYg==" }, "vuetify-loader": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/vuetify-loader/-/vuetify-loader-1.5.0.tgz", - "integrity": "sha512-JC2EVAblox2FFWE8NIUoHvQmGnnGJLrHISo2Ngciov3mWEWpt2B3qfQ3CYwmUJ7nM99DQgYDdNs26Dg3bgKzEQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vuetify-loader/-/vuetify-loader-1.6.0.tgz", + "integrity": "sha512-1bx3YeZ712dT1+QMX+XSFlP0O5k5O5Ui9ysBBmUZ9bWkAEHWZJQI9soI+qG5qmeFxUC0L9QYMCIKP0hOL/pf3Q==", "dev": true, "requires": { "file-loader": "^4.0.0", @@ -15200,15 +20840,159 @@ "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.5.1.tgz", "integrity": "sha512-w7oJzmHQs0FM9LXodfskhw9wgKBiaB+totOdb8sNzbTB2KDCEEwEs29NzBZFh/lmEK1t5tDmM1vtsO7ubG1DFw==" }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "dev": true, + "requires": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, + "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" + } + }, "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz", + "integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==", "dev": true, "requires": { - "chokidar": "^2.1.8", + "chokidar": "^3.4.1", "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.0" + }, + "dependencies": { + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "optional": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true, + "optional": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "optional": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", + "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "optional": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "optional": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "optional": true + }, + "readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "dev": true, + "optional": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "optional": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "watchpack-chokidar2": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", + "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "dev": true, + "optional": true, + "requires": { + "chokidar": "^2.1.8" } }, "wbuf": { @@ -15229,10 +21013,16 @@ "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.43.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz", - "integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.1.tgz", + "integrity": "sha512-4UOGAohv/VGUNQJstzEywwNxqX417FnjZgZJpJQegddzPmTvph37eBIRbRTfdySXzVtJXLJfbMN3mMYhM6GdmQ==", "dev": true, "requires": { "@webassemblyjs/ast": "1.9.0", @@ -15243,7 +21033,7 @@ "ajv": "^6.10.2", "ajv-keywords": "^3.4.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.1.0", + "enhanced-resolve": "^4.3.0", "eslint-scope": "^4.0.3", "json-parse-better-errors": "^1.0.2", "loader-runner": "^2.4.0", @@ -15256,7 +21046,7 @@ "schema-utils": "^1.0.0", "tapable": "^1.1.3", "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.6.1", + "watchpack": "^1.7.4", "webpack-sources": "^1.4.1" }, "dependencies": { @@ -15274,9 +21064,9 @@ } }, "webpack-bundle-analyzer": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.7.0.tgz", - "integrity": "sha512-mETdjZ30a3Yf+NTB/wqTgACK7rAYQl5uxKK0WVTNmF0sM3Uv8s3R58YZMW7Rhu0Lk2Rmuhdj5dcH5Q76zCDVdA==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.8.0.tgz", + "integrity": "sha512-PODQhAYVEourCcOuU+NiYI7WdR8QyELZGgPvB1y2tjbUpbmcQOt5Q7jEK+ttd5se0KSBKD9SXHCEozS++Wllmw==", "dev": true, "requires": { "acorn": "^7.1.1", @@ -15295,19 +21085,10 @@ }, "dependencies": { "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", + "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", "dev": true - }, - "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } } } }, @@ -15334,9 +21115,9 @@ } }, "webpack-chain": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-6.4.0.tgz", - "integrity": "sha512-f97PYqxU+9/u0IUqp/ekAHRhBD1IQwhBv3wlJo2nvyELpr2vNnUqO3XQEk+qneg0uWGP54iciotszpjfnEExFA==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-6.5.1.tgz", + "integrity": "sha512-7doO/SRtLu8q5WM0s7vPKPWX580qhi0/yBHkOxNkv50f6qB76Zy9o2wRTrrPULqYTvQlVHuvbA8v+G5ayuUDsA==", "dev": true, "requires": { "deepmerge": "^1.5.2", @@ -15437,15 +21218,6 @@ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, - "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" - } - }, "is-absolute-url": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", @@ -15458,40 +21230,6 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, - "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" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "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-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "schema-utils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", @@ -15583,15 +21321,6 @@ } } }, - "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - }, "yargs": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", @@ -15669,11 +21398,37 @@ } }, "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "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", @@ -15705,9 +21460,9 @@ "dev": true }, "windows-release": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.1.tgz", - "integrity": "sha512-Pngk/RDCaI/DkuHPlGTdIkDiTAnAkyMjoQMZqRsxydNl1qGXNIoZrB7RK8g53F2tEgQBMqQJHQdYZuQEEAu54A==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.3.tgz", + "integrity": "sha512-OSOGH1QYiW5yVor9TtmXKQvt2vjQqbYS+DqmsZw+r7xDwLXEeT3JGW0ZppFmHx4diyXmxt238KFR3N9jzevBRg==", "dev": true, "requires": { "execa": "^1.0.0" @@ -15793,6 +21548,15 @@ "typedarray-to-buffer": "^3.1.5" } }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, "x-is-string": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", @@ -15805,6 +21569,12 @@ "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "dev": true }, + "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 + }, "xml2js": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", @@ -15821,6 +21591,12 @@ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", "dev": true }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "xregexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", @@ -15852,9 +21628,9 @@ "dev": true }, "yargs": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", - "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, "requires": { "cliui": "^6.0.0", @@ -15867,7 +21643,7 @@ "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^18.1.1" + "yargs-parser": "^18.1.2" }, "dependencies": { "find-up": { @@ -15889,15 +21665,6 @@ "p-locate": "^4.1.0" } }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, "p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", @@ -15907,12 +21674,6 @@ "p-limit": "^2.2.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 000000000..1f9edc4cb --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,98 @@ +{ + "name": "codex", + "version": "0.5.0", + "private": true, + "description": "ui for codex api", + "scripts": { + "serve": "vue-cli-service serve", + "build": "vue-cli-service build --modern", + "test:unit": "vue-cli-service test:unit", + "lint": "vue-cli-service lint", + "dev": "vue-cli-service build --watch" + }, + "dependencies": { + "axios": "^0.20.0", + "core-js": "^3.6.4", + "normalize.css": "^8.0.1", + "reconnecting-websocket": "^4.4.0", + "vue": "^2.6.11", + "vue-router": "^3.4.3", + "vue2-filters": "^0.11.0", + "vuetify": "^2.3.9", + "vuex": "^3.5.1" + }, + "devDependencies": { + "@mdi/font": "^5.5.55", + "@mdi/js": "^5.5.55", + "@vue/cli-plugin-babel": "~4.5.4", + "@vue/cli-plugin-eslint": "~4.5.4", + "@vue/cli-plugin-unit-jest": "^4.5.4", + "@vue/cli-plugin-vuex": "~4.5.4", + "@vue/cli-service": "~4.5.4", + "@vue/eslint-config-prettier": "^6.0.0", + "@vue/test-utils": "^1.0.4", + "babel-core": "^7.0.0-bridge.0", + "babel-eslint": "^10.1.0", + "eslint": "^7.7.0", + "eslint-config-adjunct": "^4.8.5", + "eslint-config-prettier": "^6.11.0", + "eslint-plugin-array-func": "^3.1.7", + "eslint-plugin-eslint-comments": "^3.2.0", + "eslint-plugin-html": "^6.0.3", + "eslint-plugin-jest": "^23.20.0", + "eslint-plugin-jest-async": "^1.0.3", + "eslint-plugin-json": "^2.1.2", + "eslint-plugin-json-format": "^2.0.1", + "eslint-plugin-markdown": "^1.0.2", + "eslint-plugin-no-constructor-bind": "^2.0.3", + "eslint-plugin-no-secrets": "^0.6.8", + "eslint-plugin-no-unsanitized": "^3.1.2", + "eslint-plugin-no-use-extend-native": "^0.5.0", + "eslint-plugin-only-warn": "^1.0.2", + "eslint-plugin-optimize-regex": "^1.2.0", + "eslint-plugin-prettier": "^3.1.4", + "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-scanjs-rules": "^0.2.1", + "eslint-plugin-security": "^1.4.0", + "eslint-plugin-simple-import-sort": "^5.0.3", + "eslint-plugin-sonarjs": "^0.5.0", + "eslint-plugin-switch-case": "^1.1.2", + "eslint-plugin-unicorn": "^21.0.0", + "eslint-plugin-vue": "^7.0.0-beta.2", + "eslint-plugin-vue-scoped-css": "^1.0.0", + "prettier": "^2.0.5", + "prettier-plugin-package": "^1.0.0", + "sass": "^1.26.10", + "sass-loader": "^9.0.3", + "typeface-roboto": "0.0.75", + "vue-cli-plugin-vuetify": "^2.0.7", + "vue-eslint-parser": "^7.1.0", + "vue-template-compiler": "^2.6.12", + "vuetify-loader": "^1.6.0", + "webpack-bundle-tracker": "^0.4.3" + }, + "optionalDependencies": { + "fsevents": "^2.1.3" + }, + "prettier": { + "trailingComma": "es5", + "arrowParens": "always", + "tabWidth": 2 + }, + "jest": { + "moduleFileExtensions": [ + "js", + "json", + "ts", + "vue" + ], + "transform": { + ".*\\.(vue)$": "vue-jest" + }, + "collectCoverage": true, + "collectCoverageFrom": [ + "**/*.{js,vue}", + "!**/node_modules/**" + ] + } +} diff --git a/codex_vue/public/css/normalize.css b/frontend/public/css/normalize.css similarity index 100% rename from codex_vue/public/css/normalize.css rename to frontend/public/css/normalize.css diff --git a/frontend/public/img/android-chrome-192x192.png b/frontend/public/img/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..e249bb2f40768562cfc80e30fe8a9add830664f3 GIT binary patch literal 9717 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 A%m4rY literal 0 HcmV?d00001 diff --git a/frontend/public/img/favicon-32x32.png b/frontend/public/img/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..bc2cea47216b65d01f134289c2a67e41dd2e8d9c GIT binary patch literal 1117 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 literal 0 HcmV?d00001 diff --git a/frontend/public/img/mstile-150x150.png b/frontend/public/img/mstile-150x150.png new file mode 100644 index 0000000000000000000000000000000000000000..145479730721aa021328732cf6670b8661a0dbf4 GIT binary patch literal 7220 zcmbVRg;!Kxv>rkj5Rj2UKnIBd8A6bf7-DE8hYpbrg%JrAB!?bqknWc54v`qTr39o~ zkQ9&<-uPSZA9(Msb=SS??sL{TckgelowZ`}X&LaYbH5&bY*Q$afc zx(Vn>|My`A!M_Yj1P(1E0cJkxx?a2P{cWj#-?}gn&Cb&I6sNe*1|+KMx&1UnEt&wu ztV(ZFg(Q%84l>K+BI{%0j8~OKvj`4;e#8*148wJ*w{fOave1VgIyA%U0_i?Rp&pkm zEc|(V8tx4BI%#5SH07&ODc>*O*84hM-s+vNb8_7@aFYtxsZFga8_eVP2i>x^X8i!uFo9TsIRewV=k_3+&e}S-K($d2H!} zrFve5C23QE?jm-|*7M=49^Z-J* zM!HDX6$*8w0?SjG7U#YK0cC@35hHoTsKPGjJ;Re|><{~bN5~RsZYyIYQ9Ljb*Jlug z_(PcvM+FcVOx-bg$Lgx@X0`(bH*H*usL&xxt#0i1sMBkH1rQSKcz=`XwChzZAsF>d zoiUV@2==b$q3e@-?U@aY)p244&Oj_Ug)R>h95j9MyzptkY zKPnRX#JJYL-?nLMx+TA3nM^_??QrL_<(rp)f;bB9=qIZ{ig@R67~wmCS05n39G|R| z1vMpL_Q8*%giA#6Ym^{A6)#a!X|y%^<5&PX&|q4C9r?58%vVk}dHGw_sRo)VW4`DW? z6Y7$Q_{!t$@=*a40DXcKC@FlQLlD3igB5axBq5SFVQAUM&JzRup{ziqHhK)jtt4%e z#5OEvZW`DyvXpooRst zU&b(9njQ^LQMoMi`J)U?k6JIa;;Z+k6QbeB{TA9Fz0h3=`ZmJJ=?ZTl-WBz2lZg+$ zwa%Rz!t5s1g@X*gpjalFMa|~>a;RHSW;bLTr&Z&avbl!bj8v4%4L0>l#`eKEMbEK(a{9XDTutA1}DxN^owh3CAyUVSq)MXs(C( z!L8lqy*Ni*w=TPmE)FHt`T^AJ?pb>dnY3q37dC`AzkhV?oZ(g8$}b((RmO%AARajV z_efMixiD?ReQU6L4P?K1`mg4SNgCEBFcCR^!hSAG@63&KF=2$j6M@v)(W>`yfu|0S zFYOu2TI$;cX&6P73CDh}eQqSARtk#p#n8$eIN`Av-9_X)K|V*q1xm;e9`y0p2ew|k zwZJk7qQM@-Dhj^FGN7l}`%-S|gZc~b!I4()#CE&E(abbaqe3}=41)n@-4WhXbX0|Ab*fZxg3O? zLxvYGC&bpbys$p*Y^yhOa~s^!J7-2?ehZ5D(9D1bo;=BTX;0JHR2&tUZy8{a2#5A*SB2@Y;r(D_Q}@6BWx zdzq%pX1uDleF`1;EfQDtSJhYx^t z=bdqv4HtWy=_xyIqoS$bB&FjVha|Np^F?Btlxdhg=MZJJ+vYJbIO;&e;`GW>b;e){=#mL8_F|Q;93$LzSldpyzYpV+1 zb+>LxI*6EkbpF*o1(lI#Dxs4F>EO$FahQ^)^0H3!EnH)BdYDu{c~=66SI)0BSt#wj z$b&p>lG8B75IaNnAAot`(yQeYH3xSq63IcLsM?9*N~YlVAw|x=>KLSaUXGtC@2W`z z+)0125iPilt^gY)Wg-VfEx3;*@qSTE0-H;Uz*;sXRU4>#8OE7@spxkc%KR}K@yhf| zZO7284Imd_zWXfc^s9Nm$jhhQH)nzTElob2-Z#HYMLhyea;yGC@+Y zP2%zDgBq>%+0*xlZ*sxR#-7Ua8Qv(d;Y?tXzwzILa@yt3lR=B#FXHOcq+AO}w?E_Y z7OY5!yILc+eIw9(St4#h5oSJBa#ZI+%$hU79n|s&sFZp4!S@LHm-p=0`{DwffB)dx zUogTMWzmJV(RjpVpx%xS9TsyNJIM^uHLf2)%BiL(m|8NsxxedeZ7k%cpk~u71JbF9 z625Y+)FezAP^i6y^LawTsT7Ze@dm0C)=|EvD`8kxP{mwQd#Pag>7>I?+g+CUq33XA zd6XvFacfIh-I)D2`=z@1D(q^IL6~|={B@t3S$>Ybj=9>)KetUIM61H=jOLVo<35;h zlXeZVP#Y;CMGqI1vjf+Dj)?b7!yqLpRdL` zDB8uZZu^bFspubw9$`AT|L95liVR6gtWoA8ojQ`d3Ug{T| z_t#Ww-}&O8-pPD8KV;w>KPl8ZlZS%aFG}vxm+Q8?*-0k#Odws;?i*1Az`FUNW@vyn zJ3iftjB}FDfj?+)@B~QQB*@lSwZ9xK_06jKrUuot5obQeo^4Wzk^SCNvkwUT_B?K1 zI+=G`>=!usWrk@8F;tcb5134EaPGFcA*^0};Iyf3C7 z2DjyWi49Ry^ySO1m$zX#Z+V`p*4;-BQ@R!0zV@d|n_?F;g>7+c-D0 z&KeY=DQo^BCrFT`AE5o+$S2!{dJ{4wIboici#dLDKLUGU+Z49E(pzEuCZHF`tKYP} z_w>>R&J$!~<48`fvm#ZWM!F27&=2edD^&{pz;-!~*BLr^mbmT*5Y?6NH+!ljIqbP* z_to!@AoGDriU6I)4d3vTdf}fN0fz$lrNW}SUUg0bG5wTxMB-8Kp4-95ecOMAYeTSe zkDxEn=GN~Zs&_ub5kYi-Vz$w{j+h#sVs)aC|JoRoVA0hJI2(x@=P zdK>tWWu?Rw%D;SmEH4d)yDDg#Rj+Jz9|yESh^7)+;9a&Y<7?Pmu^2UWSMMh?T6^wX zn=VteXRE&+&4{Fo1-klN4;F&HvN0o~xqRNgzq8=P?!Op@_Kx@`L9 zLZn5kz1~Map*m(XkWc6G+qv*}s?%*w&Fe$o@VASSltn7LA57fLSp8dJ+g(uRK_!IY zqY}{d5@SyD-(vwl{hQ#(zq`Eqe#YcbB6jbiXwZUl=x(1MFKp4H^DuB|9(LD=&+ zg7*6IQt@n!J*Rm$oJD;Rx!So}l-iKj|N4Pli|`OsJX7j(5JANMCk^b z==`s*c$nTSuFVh-woRM$O_dxoF1rUHteBrtRRC%P%^Q;v)y`I2IX+rwq}{lENLt+v z@@xrw|9f#oP(XK*oDwKKegu7(m^=KX*&Z)MCf1{$d2aCPUG4GvP}d z=Po{7?7gD?ud@%XzLy1r)layMd?$Z_rD26OeC$NfF(-`G@_e)sSy1%;>ra`N!l{&^ z$OYCT*}8Q44&Tq`cWwD6}5Rg1}U+q z9QP%C_&jI7_Uxy~sna^6wuz7l#Rv8E&+4JWc0}u#7CiMMtaR!MQG(O7-Z`+Sv~B8G zT%1|HAhoC~;d2=tP(jVpSH7M=mLpKaAS6{Jpy-pBbyGyE?H>*e+qnxjoE%&nPZ3N| zKMGeM%*YV)1}1JReCeZTuP}ap%sA-{+{CK+ba}W(d(U0=YV_bDs(1e@q_zK|_;xqx zW1>on2*OYBtfbI-xBWzC)MCo-&h&6w4ndn2ftDxi=2c0T3>spD+{#}~-{5O_*_;*s z&yAlpnym_oOuHp6_$+OU59~UlSOmO3PXn=4N` zVv~CIqiSJBJoi7*G?Lquwm}SGc$eU0WqFjS&INi*i5Juw(DRTzjGfnhKD}yi&qvv> zDErL2?C+%P6QB}vm9iCt945<66R&Relt2M_a2;b5a*gL|%mRMGZaU_9Lt|uTl32Ec zm5mEK>6u~wNN9xvn@t4@!J=(GrP@74R&$r#7454$Vf!BmpqN})88%Qz=qqAOw6m_! zA|+Iu2y;F2rc>Skna~@thu0O&qd4D2vX&lLi z9A-c6JPB%H1}Y`K0e7>396ze>LGX(`pEsU8N653+9TVWyL0+UFG|4|O6$VAVgX;%| z)~C7b;FB@(P^5tYKx}>*o)aTZIPgA0^-IP66u0bGJFyKs8OD?xDmdV2n|6E@g8SB_ zf1Qic*Uyk6Vtk_1Q`J9=6W~v&@+7tq@8YDTk}C_cOlOApM(Zlq!5njvU;~P6DJ`sF zJ%yjRd!+DNQ0%+|$j7}?GT_Cbcvt3zXiH#(JIT6_?u&Wh+e-)1+18nCnV&W)?8R+A z0zH)WJ$I>X-w3TyAsUWC@Tpo5``&L|V(G0`WC=H@(eL5v`DlWu&8S$B z-#BYGkWC$ci6CSSEP<@z6;BUsM%4rWGu={GEc5+j!ZPNst@^7kwYYLIz4wjMz`E>M zp4{m%)a7)mKCi;H*CyCL!Y6OOuQ%-|!|-v>yXbHpR}8RLSv7j&vmqAav)G#OnE^1V z9PYB6K~NBDN$g35zLBsGu;C!m&CmcF8try$7_3cfTZv}Gy#1vF@9RA(gN)__( zc}_pFu6)65s{dUSb&^;aj9>>ilTJy*9<27<<@MPGl+VJ@0!D(dta4wNuC8Q6abA_H zCm4rRauEj=L%5aL`%=iyw8E>y_u~?k9ETQA)`qz((nyyGH%+9Z&^=H|B(1IjaS6W( zaBkV6&A`8CWzKh+9?_Tfp`PGi|5tkhoC7Kq*}MtyqB`3A=^`%FV=DeOaSFx7_{5Xb zwDnE*zHMr&nCw$sg!yN#Sk|mG=U6h}5$IbkS@1z{LZs6nx5^ro{L&9n?dz312B}Ld zi@MNftq0-Kf6FLkhh=*--ajnlt{RPq94zF-m$-}^k^xSkQo8xRNi{c9?Avt zF2p$wIS&5wT5Rbe+cEP_GQRbfiNchE|FWge%r5s5mk0x3)U!CcRS`=W0t|)0@-zoN zrk!xmi2=xkVu;FV!Cn5@>S6-RRz;WDx$V(f+zf#Gg-g@`@ZoCWzo8?HhGlL#f1TLd zP(4xWZv9c_9R?v#ns`n)N43Rst&l9EyKSd$*#~GRZc;}HR7|NoAz7N0z+38vgEfq$ zI)&Y4$l;F)f%zPFbr_>+b(G`tP7$#0R(a556E!!96L;VBiGRnUMHv zEFOCSc5&3s={e`rHB%isCq@Jm>{*lOwc;CYN zQYWX{b7u!Tl{fSFpkE=DY(w<~UF86@;Qrj`+>ygLJY#J0@?~XrCSnhQj!b$0MQp5E zkRakmB94qTbvrRWk46}!?zJ1O-lR9Nc8lo?T|{`6xL8cGl4hGYgQ@ynJM6e5izqQc z4Y*yLLrcwV^cvSIpQ2BDV@n7#w|goz@N^ZfyBN1EM3C>e-Gmvk@0Vz<9`YX%IzJPk zQM6x~I#Qo3KP6xys);Ev_)QO$(mU~>etE*caLY7&yIzHMgfC6H+o!35 zum}SbK@FVG3Dc;cj37-uFRz>Uz5n6_CVR~(=C0hj^ULOb-CFzUEkYQ74!nA(Vs)xI zY}k`vAo&UzsFs7v(`Eltn;9pYOshg9e}F*?uLKW=P=>NX?xzs(D{M7_yE#1vmn{jv z@}Ur_2r>HGtc1ZEHPaA}ezJCLEIt(sTwS^-owxl`p@@e7h6aDzO4}VA3{wqs?$a3f z6_Lc|uFlT=-N=>GVbz}=u@%P&YWM$>h*jY>Y1EstqzIr8j7*=(YSN|tl7e6oS%1vI; zMQW)qc>PahF8KXA*s#CyasRHD`n=eEx!k*>&pjKxT(MG{hgpd<-K^iKZfBFDLznmW z)X#sPczC6I9sMH}0XdKt3#UQi_%oNdW%57{na;=sGO(IgIHD+MUn2G>Zh!A_ytj<# zg#!Kvz>SqV)m1CbRO&4zM(=jqGwRqtnrCST$82~O68v^ixC;gUHL$Npjb(;B1ksoG zG}~AvmG)c;ix(X~L!c+x<=`$3Ud9$r|>h_K(H-px7 zglMAK1JOnT908D&8G?2MyptjdAfl#1i2h$s-Toir%?Oq>guS0LK6Cpw`MH9+e3`77 G-~Rxg3`NBN literal 0 HcmV?d00001 diff --git a/frontend/public/img/safari-pinned-tab.svg b/frontend/public/img/safari-pinned-tab.svg new file mode 100644 index 000000000..5109fdf69 --- /dev/null +++ b/frontend/public/img/safari-pinned-tab.svg @@ -0,0 +1,44 @@ + + + + +Created by potrace 1.11, written by Peter Selinger 2001-2013 + + + + + + + + + diff --git a/frontend/public/img/webpack.css b/frontend/public/img/webpack.css new file mode 100644 index 000000000..709bb3455 --- /dev/null +++ b/frontend/public/img/webpack.css @@ -0,0 +1,25 @@ +/* This file only exists for webpack to copy these images */ +a { + background: url("android-chrome-192x192.png"); +} +b { + background: url("android-chrome-512x512.png"); +} +c { + background: url("apple-touch-icon.png"); +} +d { + background: url("favicon-16x16.png"); +} +e { + background: url("favicon-32x32.png"); +} +f { + background: url("favicon.ico"); +} +g { + background: url("mstile-150x150.png"); +} +h { + background: url("safari-pinned-tab.svg"); +} diff --git a/frontend/public/index.html b/frontend/public/index.html new file mode 100644 index 000000000..c7e14d24e --- /dev/null +++ b/frontend/public/index.html @@ -0,0 +1 @@ + diff --git a/codex_vue/public/robots.txt b/frontend/public/robots.txt similarity index 100% rename from codex_vue/public/robots.txt rename to frontend/public/robots.txt diff --git a/codex_vue/src/api/auth.js b/frontend/src/api/auth.js similarity index 88% rename from codex_vue/src/api/auth.js rename to frontend/src/api/auth.js index 1838231de..17f884a2b 100644 --- a/codex_vue/src/api/auth.js +++ b/frontend/src/api/auth.js @@ -1,4 +1,6 @@ -import { ajax } from "./base"; +import { ajax, ROOT_PATH } from "./base"; + +export const ADMIN_URL = `${ROOT_PATH}admin/`; const registerEnabled = async () => { return await ajax("get", "/auth/register"); diff --git a/codex_vue/src/api/base.js b/frontend/src/api/base.js similarity index 71% rename from codex_vue/src/api/base.js rename to frontend/src/api/base.js index a429a38fa..b45c1be3e 100644 --- a/codex_vue/src/api/base.js +++ b/frontend/src/api/base.js @@ -1,7 +1,8 @@ import axios from "axios"; -export const BASE_URL = "/api"; +export const ROOT_PATH = `${window.rootPath}`; +export const API_PREFIX = `${ROOT_PATH}api`; const CONFIG = { - baseURL: BASE_URL, + baseURL: API_PREFIX, withCredentials: true, xsrfCookieName: "csrftoken", xsrfHeaderName: "X-CSRFTOKEN", diff --git a/codex_vue/src/api/browser.js b/frontend/src/api/browser.js similarity index 53% rename from codex_vue/src/api/browser.js rename to frontend/src/api/browser.js index ac7981fbf..5249c71a5 100644 --- a/codex_vue/src/api/browser.js +++ b/frontend/src/api/browser.js @@ -1,8 +1,9 @@ import ReconnectingWebSocket from "reconnecting-websocket"; -import { ajax } from "./base"; +import { ajax, ROOT_PATH } from "./base"; const BROWSE_BASE = "/browse"; +const BASE_URL = `${location.host}${ROOT_PATH}`; const debug = process.env.NODE_ENV !== "production"; @@ -20,18 +21,34 @@ const setMarkRead = ({ group, pk, finished }) => { }); }; +const WS_TIMEOUT = 19000; + +const keepAlive = (ws) => { + if (ws.OPEN) { + // websocket receiver requires json. send the minimal as a ping. + ws.send("{}"); + } + setTimeout(() => keepAlive(ws), WS_TIMEOUT); +}; + // websocket only used for the browser now. export const getSocket = () => { - let socket_proto = "ws"; + let socketProto = "ws"; if (window.location.protocol === "https:") { - socket_proto += "s"; + // this should never happen. use a webserver to terminate ssl.t s + socketProto += "s"; } - const socket_uri = `${socket_proto}://${location.host}`; - return new ReconnectingWebSocket(socket_uri, undefined, { + const socketURI = `${socketProto}://${BASE_URL}`; + const ws = new ReconnectingWebSocket(socketURI, undefined, { debug, }); + keepAlive(ws); + return ws; }; +export const getCoverSrc = (coverPath) => + `${ROOT_PATH}static/covers/${coverPath}`; + export default { getBrowseOpened, getBrowseObjects, diff --git a/codex_vue/src/api/metadata.js b/frontend/src/api/metadata.js similarity index 69% rename from codex_vue/src/api/metadata.js rename to frontend/src/api/metadata.js index 24ae5b5a1..919377731 100644 --- a/codex_vue/src/api/metadata.js +++ b/frontend/src/api/metadata.js @@ -1,4 +1,4 @@ -import { ajax } from "./base"; +import { ajax, API_PREFIX } from "./base"; const COMIC_BASE = "/comic"; @@ -7,7 +7,7 @@ const getComicMetadata = (pk) => { }; export const getDownloadURL = (pk) => { - return `/api{$COMIC_BASE}/${pk}/archive.cbz`; + return `${API_PREFIX}${COMIC_BASE}/${pk}/archive.cbz`; }; export default { diff --git a/codex_vue/src/api/reader.js b/frontend/src/api/reader.js similarity index 75% rename from codex_vue/src/api/reader.js rename to frontend/src/api/reader.js index 4e22ba88e..e183ea247 100644 --- a/codex_vue/src/api/reader.js +++ b/frontend/src/api/reader.js @@ -1,11 +1,7 @@ -import { ajax, BASE_URL } from "./base"; +import { ajax, API_PREFIX } from "./base"; const COMIC_BASE = "/comic"; -const getComicReader = (pk) => { - return ajax("get", `${COMIC_BASE}/${pk}/open`); -}; - const getComicOpened = (pk) => { return ajax("get", `${COMIC_BASE}/${pk}`); }; @@ -23,11 +19,10 @@ const setComicDefaultSettings = (data) => { }; export const getComicPageSource = ({ pk, pageNumber }) => { - return `${BASE_URL}${COMIC_BASE}/${pk}/${pageNumber}/p.jpg`; + return `${API_PREFIX}${COMIC_BASE}/${pk}/${pageNumber}/p.jpg`; }; export default { - getComicReader, getComicOpened, getComicPageSource, setComicBookmark, diff --git a/codex_vue/src/app.vue b/frontend/src/app.vue similarity index 100% rename from codex_vue/src/app.vue rename to frontend/src/app.vue diff --git a/codex_vue/src/browser.vue b/frontend/src/browser.vue similarity index 94% rename from codex_vue/src/browser.vue rename to frontend/src/browser.vue index bc503a7a9..9dbf6c373 100644 --- a/codex_vue/src/browser.vue +++ b/frontend/src/browser.vue @@ -1,5 +1,5 @@ @@ -160,10 +157,12 @@ import { mdiArrowUp, mdiCloseCircle, mdiDotsVertical } from "@mdi/js"; import { mapGetters, mapState } from "vuex"; +import { ADMIN_URL } from "@/api/auth"; import { getSocket } from "@/api/browser"; import AuthButton from "@/components/auth-dialog"; import BrowseCard from "@/components/browse-card"; import FilterSubMenu from "@/components/filter-sub-menu"; +import PlaceholderLoading from "@/components/placeholder-loading"; export default { name: "Browser", @@ -171,13 +170,14 @@ export default { AuthButton, BrowseCard, FilterSubMenu, + PlaceholderLoading, }, data() { return { mdiArrowUp, mdiDotsVertical, socket: undefined, - noLibrariesTimeout: false, + adminURL: ADMIN_URL, }; }, computed: { @@ -195,7 +195,6 @@ export default { ...mapState("auth", { isAdmin: (state) => state.user && (state.user.is_staff || state.user.is_superuser), - adminURL: (state) => state.adminURL, }), ...mapGetters("browser", ["rootGroupChoices", "filterNames"]), upTo: function () { @@ -243,7 +242,7 @@ export default { }, set(value) { if (value === null || value === undefined) { - console.log(`bookmarkFilter was ${value}. Setting to 'ALL'`); + console.warn(`bookmarkFilter was ${value}. Setting to 'ALL'`); value = "ALL"; } this.setFilter("bookmark", value); @@ -302,7 +301,6 @@ export default { this.$store.dispatch("browser/browseOpened", this.$route.params); } }); - setTimeout(() => (this.noLibrariesTimeout = true), 5000); }, beforeDestroy() { if (this.socket) { @@ -330,7 +328,6 @@ export default { this.setSubSetting("filters", filterName, value); }, clearFilters: function () { - console.log("CFS"); this.$store.dispatch("browser/clearFilters"); }, closeFilterSelect: function () { @@ -367,6 +364,7 @@ export default { margin-top: 96px; margin-left: 15px; overflow: auto; + text-align: center; } .sortArrow { width: 20px; @@ -432,6 +430,9 @@ export default { #settingsMenu { background-color: #121212; } +#progressBar { + margin-top: 40px; +} #noLibraries { text-align: center; } diff --git a/frontend/src/choices/browserChoices.json b/frontend/src/choices/browserChoices.json new file mode 100644 index 000000000..cb855a852 --- /dev/null +++ b/frontend/src/choices/browserChoices.json @@ -0,0 +1,30 @@ +{ + "bookmarkFilter": [ + { "text": "All", "value": "ALL", "default": true }, + { "text": "Unread", "value": "UNREAD" }, + { "text": "In Progress", "value": "IN_PROGRESS" } + ], + "rootGroup": [ + { "text": "Publishers", "value": "r" }, + { "text": "Imprints", "value": "p", "default": true }, + { "text": "Series", "value": "i" }, + { "text": "Volumes", "value": "s" }, + { "text": "Comics", "value": "v" }, + { "text": "Folder View", "value": "f" } + ], + "settingsGroup": [ + { "text": "Publishers", "value": "p", "default": true }, + { "text": "Imprints", "value": "i" }, + { "text": "Series", "value": "s" }, + { "text": "Volumes", "value": "v", "default": true } + ], + "sort": [ + { "text": "Name", "value": "sort_name", "default": true }, + { "text": "Date Published", "value": "date" }, + { "text": "Date Added", "value": "created_at" }, + { "text": "Page Count", "value": "page_count" }, + { "text": "File Size", "value": "size" }, + { "text": "User Rating", "value": "user_rating" }, + { "text": "Critical Rating", "value": "critical_rating" } + ] +} diff --git a/frontend/src/choices/readerChoices.json b/frontend/src/choices/readerChoices.json new file mode 100644 index 000000000..c26a1fae6 --- /dev/null +++ b/frontend/src/choices/readerChoices.json @@ -0,0 +1,7 @@ +{ + "fitTo": [ + { "text": "Height", "value": "HEIGHT" }, + { "text": "Width", "value": "WIDTH", "default": true }, + { "text": "Original Size", "value": "ORIG" } + ] +} diff --git a/codex_vue/src/components/auth-dialog.vue b/frontend/src/components/auth-dialog.vue similarity index 72% rename from codex_vue/src/components/auth-dialog.vue rename to frontend/src/components/auth-dialog.vue index b49867c5e..10e24e54e 100644 --- a/codex_vue/src/components/auth-dialog.vue +++ b/frontend/src/components/auth-dialog.vue @@ -22,9 +22,7 @@ @@ -54,12 +52,8 @@ type="password" /> - - Login - - - Register - + Login + Register
@@ -58,6 +61,7 @@ @@ -247,6 +280,9 @@ export default { padding-top: 5px; color: gray; } +.orderValue { + color: gray; +} @media #{map-get($display-breakpoints, 'sm-and-down')} { .browseTile { padding: 8px; diff --git a/frontend/src/not-found.vue b/frontend/src/not-found.vue index e00471a27..0c8c7cc95 100644 --- a/frontend/src/not-found.vue +++ b/frontend/src/not-found.vue @@ -1,9 +1,16 @@ @@ -39,4 +46,8 @@ export default { font-size: 70vh; opacity: 25%; } +#foreground { + text-align: center; + z-index: 100; +} diff --git a/poetry.lock b/poetry.lock index ca8678d2a..3a30b6137 100644 --- a/poetry.lock +++ b/poetry.lock @@ -45,12 +45,13 @@ description = "Classes Without Boilerplate" name = "attrs" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "20.1.0" +version = "20.2.0" [package.extras] dev = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "sphinx-rtd-theme", "pre-commit"] docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] tests = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] +tests_no_zope = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] [[package]] category = "dev" @@ -168,7 +169,7 @@ description = "An API for reading comic archives" name = "comicbox" optional = false python-versions = ">=3.7,<4.0" -version = "0.1.3" +version = "0.1.4" [package.dependencies] parse = ">=1.15,<2.0" @@ -1109,8 +1110,8 @@ atomicwrites = [ {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, ] attrs = [ - {file = "attrs-20.1.0-py2.py3-none-any.whl", hash = "sha256:2867b7b9f8326499ab5b0e2d12801fa5c98842d2cbd22b35112ae04bf85b4dff"}, - {file = "attrs-20.1.0.tar.gz", hash = "sha256:0ef97238856430dcf9228e07f316aefc17e8939fc8507e18c6501b761ef1a42a"}, + {file = "attrs-20.2.0-py2.py3-none-any.whl", hash = "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc"}, + {file = "attrs-20.2.0.tar.gz", hash = "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594"}, ] beautifulsoup4 = [ {file = "beautifulsoup4-4.9.1-py2-none-any.whl", hash = "sha256:e718f2342e2e099b640a34ab782407b7b676f47ee272d6739e60b8ea23829f2c"}, @@ -1201,8 +1202,8 @@ coloredlogs = [ {file = "coloredlogs-14.0.tar.gz", hash = "sha256:a1fab193d2053aa6c0a97608c4342d031f1f93a3d1218432c59322441d31a505"}, ] comicbox = [ - {file = "comicbox-0.1.3-py3-none-any.whl", hash = "sha256:56820370ecc05ef7505b8a1a8d0e019c665eebf0824330a14c99f340829dc263"}, - {file = "comicbox-0.1.3.tar.gz", hash = "sha256:c48d30d807d183b9d108ae2e76a8d5113f91d1844bc71e0b9b7d43acaaa276cc"}, + {file = "comicbox-0.1.4-py3-none-any.whl", hash = "sha256:eb01053b7005e57af3c1d144ac9fa9b09049d8db1b641245046f7251d3963ff3"}, + {file = "comicbox-0.1.4.tar.gz", hash = "sha256:12fb5ce7e202a03687cda0d854496d6170d0cfd50cc195dbfb04db935ada6742"}, ] coverage = [ {file = "coverage-5.2.1-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:40f70f81be4d34f8d491e55936904db5c527b0711b2a46513641a5729783c2e4"}, diff --git a/pyproject.toml b/pyproject.toml index 9d9253c08..77b744fc1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = ["poetry.masonry.api"] [tool.poetry] name = "codex" -version = "0.5.8" +version = "0.5.9" description = "A comic archive web server." license = "GPL-2.0-only" authors = ["AJ Slater "] From 41727bf4215fc4f9af6f1d829e11b4b8ff240ce1 Mon Sep 17 00:00:00 2001 From: AJ Slater Date: Tue, 8 Sep 2020 13:54:07 -0700 Subject: [PATCH 028/528] Squashed commit of the following: commit 9f22f50e97ecc743270e26217012d8d5097016dc Author: AJ Slater Date: Tue Sep 8 13:53:41 2020 -0700 use base images when building runnable docker --- Dockerfile | 36 +++++++----------------------------- build-runnable-image.sh | 2 +- docker-env | 3 ++- 3 files changed, 10 insertions(+), 31 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7a9123c5a..0dba88a2c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,40 +1,18 @@ -ARG BASE_VERSION -FROM ajslater/python-alpine:$BASE_VERSION AS codex-install -ARG PKG_VERSION -LABEL version python${BASE_VERSION}_codex-${PKG_VERSION} - -RUN echo "**** install system wheel building packages ****" && \ - apk add --no-cache \ - bsd-compat-headers \ - build-base \ - libffi-dev \ - libwebp-dev \ - openssl-dev \ - yaml-dev \ - jpeg-dev \ - zlib-dev +ARG INSTALL_BASE_VERSION +ARG RUNNABLE_BASE_VERSION +FROM ajslater/codex-install-base:${INSTALL_BASE_VERSION} AS codex-install -RUN pip3 install wheel # TODO replace with: # RUN pip3 install codex COPY dist/*.whl /tmp/ RUN pip3 wheel /tmp/*.whl --wheel-dir=/wheels -FROM ajslater/python-alpine:$BASE_VERSION -LABEL version python${BASE_VERSION}_codex-${PKG_VERSION} - -RUN echo "*** install system runtime packages ***" && \ - apk add --no-cache \ - libffi \ - libwebp \ - openssl \ - yaml \ - jpeg \ - zlib \ - unrar +FROM ajslater/codex-base:${RUNNABLE_BASE_VERSION} +ARG PKG_VERSION +LABEL version python${RUNNABLE_BASE_VERSION}_codex-${PKG_VERSION} RUN echo "*** install python wheels ***" -COPY --from=codex-install /wheels /wheels + COPY --from=codex-install /wheels /wheels RUN pip3 install --no-index --find-links=/wheels /wheels/codex*.whl diff --git a/build-runnable-image.sh b/build-runnable-image.sh index 32f1125d0..17d235c39 100755 --- a/build-runnable-image.sh +++ b/build-runnable-image.sh @@ -1,4 +1,4 @@ #!/bin/sh # Build a codex docker image suitable for running from Dockerfile . ./docker-env -docker build -t "$IMAGE" --build-arg "BASE_VERSION=$BASE_VERSION" --build-arg "PKG_VERSION=$PKG_VERSION" . +docker build -t "$IMAGE" --build-arg "INSTALL_BASE_VERSION=$INSTALL_BASE_VERSION" --build-arg "RUNNABLE_BASE_VERSION=$RUNNABLE_BASE_VERSION" --build-arg "PKG_VERSION=$PKG_VERSION" . diff --git a/docker-env b/docker-env index a7473b8e0..1afdbf93d 100644 --- a/docker-env +++ b/docker-env @@ -1,6 +1,7 @@ REPO=ajslater/codex IMAGE=ajslater/codex -BASE_VERSION=latest +INSTALL_BASE_VERSION=python3.8.5-alpine3.12_0.1.0-3fb89fc +RUNNABLE_BASE_VERSION=python3.8.5-alpine3.12_0.2.0-a88d3d9_0.1.0-3328e8e PKG_VERSION=v0.5.9 PUID=501 PGID=20 From 9492bd761de4c3adb405d95e4e8132673dd98edc Mon Sep 17 00:00:00 2001 From: AJ Slater Date: Tue, 8 Sep 2020 17:48:52 -0700 Subject: [PATCH 029/528] V0.5.10 (#53) * fix filtering bug * bump version * clean up comments * fix reader settings * mostly fix reader image layout * fix reader to browser uninitialized error * bump news --- NEWS | 7 +++ codex/views/browse_base.py | 8 ++-- codex/views/browser.py | 9 +++- codex/views/metadata.py | 11 +++-- codex/views/mixins.py | 4 +- codex/views/reader.py | 8 ++++ docker-env | 2 +- frontend/package-lock.json | 2 +- frontend/package.json | 2 +- frontend/src/api/browser.js | 3 +- frontend/src/api/reader.js | 4 +- frontend/src/components/reader-comic-page.vue | 22 ++------- frontend/src/reader.vue | 46 +++++++------------ frontend/src/store/modules/browser.js | 9 ++-- frontend/src/store/modules/reader.js | 46 ++++++++++++------- pyproject.toml | 2 +- 16 files changed, 95 insertions(+), 90 deletions(-) diff --git a/NEWS b/NEWS index 5e8dd16fb..c52fbf80d 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,10 @@ +v0.5.10 +* fix filtering bugs +* fix mark read/unread bugs +* fix reader settings not setting properly +* fix reader images positioning +* fix minor crash closing books with unitialized browser app + v0.5.9 * fix sorting for folder view * display sort key value in browse tile diff --git a/codex/views/browse_base.py b/codex/views/browse_base.py index c24b0962b..2ecb33e7f 100644 --- a/codex/views/browse_base.py +++ b/codex/views/browse_base.py @@ -106,19 +106,19 @@ def get_query_filters(self, choices=False): is_folder_view = self.kwargs.get("group") == self.FOLDER_GROUP if is_folder_view: if choices: + # Choices needs to get all decendant comic attributes object_filter = self.get_folders_filter() else: object_filter = self.get_parent_folder_filter() else: object_filter = self.get_browse_container_filter() - if is_folder_view or not choices: + if choices: + aggregate_filter = None + else: bookmark_filter_join = self.get_bookmark_filter() comic_attribute_filter = self.get_comic_attribute_filter() aggregate_filter = bookmark_filter_join & comic_attribute_filter - else: - aggregate_filter = None - if is_folder_view: object_filter &= aggregate_filter return object_filter, aggregate_filter diff --git a/codex/views/browser.py b/codex/views/browser.py index 378aa2509..23c376d72 100644 --- a/codex/views/browser.py +++ b/codex/views/browser.py @@ -204,9 +204,10 @@ def add_annotations(self, obj_list, model, aggregate_filter): ) ################################ - # Annotate finished & progress # + # Annotate userbookmark hoists # ################################ ub_filter = self.get_userbookmark_filter() + # Hoist up: are the children finished or unfinished? finished_aggregate = Cast( NullIf( @@ -226,8 +227,12 @@ def add_annotations(self, obj_list, model, aggregate_filter): # Hoist up the bookmark bookmark_sum = Sum("comic__userbookmark__bookmark", filter=ub_filter) + obj_list = obj_list.annotate(finished=finished_aggregate, bookmark=bookmark_sum) - # Annotate progress + + ##################### + # Annotate progress # + ##################### obj_list = self.annotate_progress(obj_list) ####################### diff --git a/codex/views/metadata.py b/codex/views/metadata.py index 9d8ceadb4..f9166666d 100644 --- a/codex/views/metadata.py +++ b/codex/views/metadata.py @@ -39,18 +39,19 @@ class UserBookmarkFinishedView(APIView, SessionMixin, UserBookmarkMixin): def patch(self, request, *args, **kwargs): """Mark read or unread recursively.""" - browse_type = self.kwargs.get("browse_type") - pk = self.kwargs.get("pk") - serializer = UserBookmarkFinishedSerializer(data=request.data) serializer.is_valid(raise_exception=True) + browse_type = self.kwargs.get("browse_type") relation = BrowseView.GROUP_RELATION.get(browse_type) - comics = Comic.objects.filter(**{relation: pk}).only("pk") + pk = self.kwargs.get("pk") + # Optimizing this call with only seems to fail the subsequent updates + comics = Comic.objects.filter(**{relation: pk}) updates = {"finished": serializer.validated_data.get("finished")} for comic in comics: - # can't do this in bulk if using update_or_create + # can't do this in bulk if using update_or_create withtout a + # third party packages. self.update_user_bookmark(updates, comic=comic) return Response() diff --git a/codex/views/mixins.py b/codex/views/mixins.py index 258388d4e..e60a24514 100644 --- a/codex/views/mixins.py +++ b/codex/views/mixins.py @@ -100,8 +100,8 @@ def get_user_bookmark(self, pk): def update_user_bookmark(self, updates, comic=None, pk=None): """Update a user bookmark.""" if comic is None: - comic = Comic.objects.only("pk").get(pk=pk) - search_kwargs = self._get_user_bookmark_search_kwargs(comic) + comic = Comic.objects.only("pk", "max_page").get(pk=pk) + search_kwargs = self._get_user_bookmark_search_kwargs(comic=comic, comic_pk=pk) if updates.get("bookmark") == comic.max_page: # Auto finish on bookmark last page updates["finished"] = True diff --git a/codex/views/reader.py b/codex/views/reader.py index 8f7796861..279942ae0 100644 --- a/codex/views/reader.py +++ b/codex/views/reader.py @@ -17,6 +17,10 @@ LOG = logging.getLogger(__name__) +NULL_READER_SETTINGS = { + "fitTo": None, + "twoPages": None, +} class ComicOpenedView(APIView, SessionMixin, UserBookmarkMixin): @@ -156,4 +160,8 @@ def put(self, request, *args, **kwargs): reader_session = self.get_session(self.READER_KEY) reader_session["defaults"] = snake_dict self.request.session.save() + + # Null out this comic's settings so it uses all comic defaults + pk = self.kwargs.get("pk") + self.update_user_bookmark(NULL_READER_SETTINGS, pk=pk) return Response() diff --git a/docker-env b/docker-env index 1afdbf93d..776f18117 100644 --- a/docker-env +++ b/docker-env @@ -2,6 +2,6 @@ REPO=ajslater/codex IMAGE=ajslater/codex INSTALL_BASE_VERSION=python3.8.5-alpine3.12_0.1.0-3fb89fc RUNNABLE_BASE_VERSION=python3.8.5-alpine3.12_0.2.0-a88d3d9_0.1.0-3328e8e -PKG_VERSION=v0.5.9 +PKG_VERSION=v0.5.10 PUID=501 PGID=20 diff --git a/frontend/package-lock.json b/frontend/package-lock.json index d21cde343..2ae873cf9 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,6 +1,6 @@ { "name": "codex", - "version": "0.5.9", + "version": "0.5.10", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/frontend/package.json b/frontend/package.json index 491555c01..0695a4dca 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "codex", - "version": "0.5.9", + "version": "0.5.10", "private": true, "description": "ui for codex api", "scripts": { diff --git a/frontend/src/api/browser.js b/frontend/src/api/browser.js index a54cd8c75..fa1861586 100644 --- a/frontend/src/api/browser.js +++ b/frontend/src/api/browser.js @@ -12,7 +12,8 @@ const getBrowseOpened = ({ group, pk, page }) => { return ajax("get", `${BROWSE_BASE}/${group}/${pk}/${page}`); }; -const getBrowseObjects = ({ group, pk, page, settings }) => { +const getBrowseObjects = ({ route, settings }) => { + const { group, pk, page } = route; return ajax("put", `${BROWSE_BASE}/${group}/${pk}/${page}`, settings); }; diff --git a/frontend/src/api/reader.js b/frontend/src/api/reader.js index e183ea247..b6d17284e 100644 --- a/frontend/src/api/reader.js +++ b/frontend/src/api/reader.js @@ -14,8 +14,8 @@ const setComicSettings = ({ pk, data }) => { return ajax("patch", `${COMIC_BASE}/${pk}/settings`, data); }; -const setComicDefaultSettings = (data) => { - return ajax("put", `${COMIC_BASE}/settings`, data); +const setComicDefaultSettings = ({ pk, data }) => { + return ajax("put", `${COMIC_BASE}/${pk}/settings`, data); }; export const getComicPageSource = ({ pk, pageNumber }) => { diff --git a/frontend/src/components/reader-comic-page.vue b/frontend/src/components/reader-comic-page.vue index b5e553ce8..2cfa87f34 100644 --- a/frontend/src/components/reader-comic-page.vue +++ b/frontend/src/components/reader-comic-page.vue @@ -1,29 +1,20 @@ diff --git a/frontend/src/components/browse-card.vue b/frontend/src/components/browse-card.vue index 217ad1eff..e4fd71f31 100644 --- a/frontend/src/components/browse-card.vue +++ b/frontend/src/components/browse-card.vue @@ -1,6 +1,6 @@ @@ -466,6 +480,9 @@ export default { font-size: small; color: gray; } +#dismissScanNotify { + margin-left: 5px; +} @import "~vuetify/src/styles/styles.sass"; @media #{map-get($display-breakpoints, 'sm-and-down')} { diff --git a/frontend/src/store/modules/browser.js b/frontend/src/store/modules/browser.js index 2b6f65a90..5ea28daed 100644 --- a/frontend/src/store/modules/browser.js +++ b/frontend/src/store/modules/browser.js @@ -259,15 +259,23 @@ const isNeedValidate = (changedData) => { }; const scanNotifyCheck = (commit, state) => { - // thundering herd control + // polite client thundering herd control const wait = Math.floor( Math.random() * (MAX_SCAN_WAIT - MIN_SCAN_WAIT) + MIN_SCAN_WAIT ); setTimeout(async () => { + console.log("checking scanNotify"); + if (state.scanNotify === null) { + // null is a special value that means it was manually dismissed. + // won't be reset until there's a true push from the server. + return; + } await API.getScanInProgress() .then((response) => { const data = response.data; + console.log("got scanNotify", { data }); commit("setScanNotify", data); + console.log("state.scanNotify", state.scanNotify); if (state.scanNotify) { return scanNotifyCheck(commit, state); } @@ -375,7 +383,9 @@ const actions = { }, scanNotify({ commit, state }, value) { commit("setScanNotify", { scanInProgress: value }); - scanNotifyCheck(commit, state); + if (value !== null) { + scanNotifyCheck(commit, state); + } }, }; From 3b30103ebe043c2c8458b05a47ce62b3883467ac Mon Sep 17 00:00:00 2001 From: AJ Slater Date: Mon, 14 Sep 2020 18:29:11 -0700 Subject: [PATCH 036/528] bump version and news --- NEWS | 4 ++++ docker-env | 2 +- frontend/package-lock.json | 2 +- frontend/package.json | 2 +- pyproject.toml | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index c688806af..2a61afd76 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +v0.5.12 +* admin page for failed imports +* snackbar tells admins when scans are happening + v0.5.11 * browser rows now adapt to browse tile size * browser covers for containers now match data we're sorting by diff --git a/docker-env b/docker-env index e9572f6f6..32bf57551 100644 --- a/docker-env +++ b/docker-env @@ -2,6 +2,6 @@ REPO=ajslater/codex IMAGE=ajslater/codex INSTALL_BASE_VERSION=python3.8.5-alpine3.12_0.1.0-3fb89fc RUNNABLE_BASE_VERSION=python3.8.5-alpine3.12_0.2.0-a88d3d9_0.1.0-3328e8e -PKG_VERSION=0.5.11 +PKG_VERSION=0.5.12 PUID=501 PGID=20 diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 3e238d09e..80a44a3ea 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,6 +1,6 @@ { "name": "codex", - "version": "0.5.11", + "version": "0.5.12", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/frontend/package.json b/frontend/package.json index 06fca1ca7..62955eb53 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "codex", - "version": "0.5.11", + "version": "0.5.12", "private": true, "description": "ui for codex api", "scripts": { diff --git a/pyproject.toml b/pyproject.toml index 8b2521966..cc7c15b47 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = ["poetry.masonry.api"] [tool.poetry] name = "codex" -version = "0.5.11" +version = "0.5.12" description = "A comic archive web server." license = "GPL-2.0-only" authors = ["AJ Slater "] From 0db9671c953c3d974f8c824a94c9c35011ffe89f Mon Sep 17 00:00:00 2001 From: AJ Slater Date: Tue, 15 Sep 2020 00:12:04 -0700 Subject: [PATCH 037/528] lint and cleanup prints --- codex/views/scan_notify.py | 1 - frontend/src/browser.vue | 10 +++++----- frontend/src/store/modules/browser.js | 3 --- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/codex/views/scan_notify.py b/codex/views/scan_notify.py index 1b157d8e3..70fb3baac 100644 --- a/codex/views/scan_notify.py +++ b/codex/views/scan_notify.py @@ -20,7 +20,6 @@ class ScanNotifyView(APIView): def get(self, request, *args, **kwargs): """Return if any libraries are scanning.""" any_in_progress = Library.objects.filter(scan_in_progress=True).exists() - print(f"{any_in_progress=} QUEUE.empty():{QUEUE.empty()}") any_in_progress |= not QUEUE.empty() serializer = ScanNotifySerializer({"scanInProgress": any_in_progress}) return Response(serializer.data) diff --git a/frontend/src/browser.vue b/frontend/src/browser.vue index 980b26b0a..cbf87d89b 100644 --- a/frontend/src/browser.vue +++ b/frontend/src/browser.vue @@ -197,7 +197,7 @@ title="dismiss notification" x-small ripple - @click="dismissScanNotify" + @click="setScanNotify(null)" >x @@ -350,7 +350,7 @@ export default { user() { this.$store.dispatch("browser/browseOpened", this.$route.params); if (this.isAdmin) { - this.$store.dispatch("browser/scanNotify", false); + this.setScanNotify(false); } }, }, @@ -370,7 +370,7 @@ export default { if (event.data === "libraryChanged") { this.$store.dispatch("browser/getBrowseObjects"); } else if (this.isAdmin && event.data === "scanLibrary") { - this.$store.dispatch("browser/scanNotify", true); + this.setScanNotify(true); } }, settingChanged: function (data) { @@ -412,8 +412,8 @@ export default { route.params.page = page; this.$router.push(route); }, - dismissScanNotify: function () { - this.$store.dispatch("browser/scanNotify", null); + setScanNotify: function (value) { + this.$store.dispatch("browser/scanNotify", value); }, }, }; diff --git a/frontend/src/store/modules/browser.js b/frontend/src/store/modules/browser.js index 5ea28daed..811e92b53 100644 --- a/frontend/src/store/modules/browser.js +++ b/frontend/src/store/modules/browser.js @@ -264,7 +264,6 @@ const scanNotifyCheck = (commit, state) => { Math.random() * (MAX_SCAN_WAIT - MIN_SCAN_WAIT) + MIN_SCAN_WAIT ); setTimeout(async () => { - console.log("checking scanNotify"); if (state.scanNotify === null) { // null is a special value that means it was manually dismissed. // won't be reset until there's a true push from the server. @@ -273,9 +272,7 @@ const scanNotifyCheck = (commit, state) => { await API.getScanInProgress() .then((response) => { const data = response.data; - console.log("got scanNotify", { data }); commit("setScanNotify", data); - console.log("state.scanNotify", state.scanNotify); if (state.scanNotify) { return scanNotifyCheck(commit, state); } From 2506c93fffe3cf237c26b559d9418634ef6f6125 Mon Sep 17 00:00:00 2001 From: AJ Slater Date: Tue, 15 Sep 2020 14:39:00 -0700 Subject: [PATCH 038/528] Squashed commit of the following: commit ee19a333161c174b387a4b2b525d04ec1d549b91 Author: AJ Slater Date: Tue Sep 15 14:38:45 2020 -0700 latest version --- NEWS | 1 + codex/latest_version.py | 103 ++++++++++++++++++++++++++ codex/serializers/browse.py | 8 ++ codex/views/browser.py | 9 +++ frontend/src/browser.vue | 36 ++++++++- frontend/src/store/modules/browser.js | 9 ++- poetry.lock | 65 +++++++++++++++- pyproject.toml | 1 + 8 files changed, 226 insertions(+), 6 deletions(-) create mode 100644 codex/latest_version.py diff --git a/NEWS b/NEWS index 2a61afd76..095beca3e 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ v0.5.12 * admin page for failed imports * snackbar tells admins when scans are happening +* report the latest version available in the browser footer tooltip v0.5.11 * browser rows now adapt to browse tile size diff --git a/codex/latest_version.py b/codex/latest_version.py new file mode 100644 index 000000000..d4ae181a1 --- /dev/null +++ b/codex/latest_version.py @@ -0,0 +1,103 @@ +from datetime import datetime +from datetime import timedelta +from logging import getLogger +from pathlib import Path + +import requests +import simplejson as json + +from pkg_resources import get_distribution +from pkg_resources import parse_version + + +DEFAULT_CACHE_ROOT = "/tmp/" + +PYPI_URL_TEMPLATE = "https://pypi.python.org/pypi/%s/json" +CACHE_TIMEDELTA = timedelta(days=1) +TIMESTAMP_KEY = "timestamp" +LATEST_VERSION_KEY = "latestVersion" +REPO_TIMEOUT = 5 + +LOG = getLogger(__name__) + + +def get_latest_version_from_cache(version_cache_fn): + """Get from cache.""" + latest_version = None + try: + # Get from cache + with open(version_cache_fn, "r") as cache_file: + latest = json.loads(cache_file.read()) + timestamp = latest[TIMESTAMP_KEY] + cache_datetime = datetime.fromtimestamp(timestamp) + + # only use if unexpired + if datetime.now() - cache_datetime > CACHE_TIMEDELTA: + latest_version = latest[LATEST_VERSION_KEY] + except Exception as exc: + LOG.debug(f"Couldn't get latest version from {version_cache_fn}") + LOG.debug(str(exc)) + return latest_version + + +def set_latest_version_to_cache(version_cache_fn, latest_version): + """Store in cache.""" + try: + data = { + TIMESTAMP_KEY: datetime.timestamp(datetime.now()), + LATEST_VERSION_KEY: latest_version, + } + data_str = json.dumps(data) + with open(version_cache_fn, "w") as cache_file: + cache_file.write(data_str) + except Exception as exc: + LOG.warn(f"Couldn't store latest version at {version_cache_fn}") + LOG.warn(str(exc)) + + +def get_latest_version( + package_name, cache_root=DEFAULT_CACHE_ROOT, repo_url_template=PYPI_URL_TEMPLATE +): + """Get the latest version from a remote repo using a cache.""" + version_cache_fn = Path(cache_root) / f"{package_name}-latest-version.json" + + latest_version = get_latest_version_from_cache(version_cache_fn) + + if latest_version is None: + # Fetch Latest Remotely + repo_url = repo_url_template % package_name + response = requests.get(repo_url, timeout=REPO_TIMEOUT) + latest_version = json.loads(response.text)["info"]["version"] + + set_latest_version_to_cache(version_cache_fn, latest_version) + + return latest_version + + +def get_installed_version(package_name): + """Get the installed version of a package.""" + distribution = get_distribution(package_name) + return distribution.version + + +def is_outdated( + package_name, + cache_root=DEFAULT_CACHE_ROOT, + repo_url_template=PYPI_URL_TEMPLATE, +): + # Installed Version + installed_version = get_installed_version(package_name) + parsed_installed_version = parse_version(installed_version) + + # Latest Version + latest_version = get_latest_version(package_name, cache_root, repo_url_template) + parsed_latest_version = parse_version(latest_version) + + result = parsed_latest_version > parsed_installed_version + LOG.debug(f"{parsed_latest_version} > {parsed_installed_version} = {result}") + + +if __name__ == "__main__": + import sys + + is_outdated(sys.argv[1]) diff --git a/codex/serializers/browse.py b/codex/serializers/browse.py index 4e3e7e5d2..6cd6a4767 100644 --- a/codex/serializers/browse.py +++ b/codex/serializers/browse.py @@ -135,11 +135,19 @@ class BrowseListSerializer(Serializer): librariesExist = BooleanField(read_only=True) # noqa: N815 +class VersionsSerializer(Serializer): + """Codex version information.""" + + installed = CharField(read_only=True) + latest = CharField(read_only=True) + + class BrowserOpenedSerializer(Serializer): """Component open settings.""" settings = BrowserSettingsSerializer(read_only=True) browseList = BrowseListSerializer(read_only=True) # noqa: N815 + versions = VersionsSerializer(read_only=True) class ScanNotifySerializer(Serializer): diff --git a/codex/views/browser.py b/codex/views/browser.py index bb42794f2..d5aa8a44b 100644 --- a/codex/views/browser.py +++ b/codex/views/browser.py @@ -25,6 +25,8 @@ from rest_framework.response import Response from stringcase import snakecase +from codex.latest_version import get_installed_version +from codex.latest_version import get_latest_version from codex.models import AdminFlag from codex.models import Comic from codex.models import Folder @@ -36,10 +38,12 @@ from codex.serializers.browse import BrowseListSerializer from codex.serializers.browse import BrowserOpenedSerializer from codex.serializers.browse import BrowserSettingsSerializer +from codex.settings import CACHE_PATH from codex.views.browse_base import BrowseBaseView from codex.views.mixins import UserBookmarkMixin +PACKAGE_NAME = "codex" LOG = logging.getLogger(__name__) @@ -574,6 +578,10 @@ def get(self, request, *args, **kwargs): browse_list = self.get_browse_list() filters = self.params["filters"] + + installed_version = get_installed_version(PACKAGE_NAME) + latest_version = get_latest_version(PACKAGE_NAME, cache_root=CACHE_PATH) + data = { "settings": { "filters": { @@ -587,6 +595,7 @@ def get(self, request, *args, **kwargs): "show": self.params.get("show"), }, "browseList": browse_list, + "versions": {"installed": installed_version, "latest": latest_version}, } serializer = BrowserOpenedSerializer(data) diff --git a/frontend/src/browser.vue b/frontend/src/browser.vue index cbf87d89b..f6c6be051 100644 --- a/frontend/src/browser.vue +++ b/frontend/src/browser.vue @@ -177,9 +177,13 @@ circle @input="routeToPage($event)" /> - codex v{{ packageVersion }} + codex v{{ versions.installed }} + state.browseLoaded, librariesExist: (state) => state.librariesExist, itemsExist: (state) => state.objList && state.objList.length > 0, - packageVersion: (state) => state.packageVersion, + versions: (state) => state.versions, scanNotify: (state) => state.scanNotify, numPages: (state) => state.numPages, }), @@ -252,6 +256,27 @@ export default { }), ...mapGetters("auth", ["isAdmin"]), ...mapGetters("browser", ["rootGroupChoices", "filterNames"]), + outdated: function () { + return this.versions.latest > this.versions.installed; + }, + outdatedClass: function () { + let cls; + if (this.outdated) { + cls = "outdated"; + } else { + cls = ""; + } + return cls; + }, + versionTitle: function () { + let title; + if (this.outdated) { + title = `v${this.versions.latest} is availble`; + } else { + title = "up to date"; + } + return title; + }, upTo: function () { if (this.showUpButton) { return { name: "browser", params: this.upRoute }; @@ -545,6 +570,9 @@ export default { #scanNotify > .v-snack__wrapper { min-width: 183px; } +.outdated { + font-style: italic; +} @import "~vuetify/src/styles/styles.sass"; @media #{map-get($display-breakpoints, 'sm-and-down')} { diff --git a/frontend/src/store/modules/browser.js b/frontend/src/store/modules/browser.js index 811e92b53..d1804e8de 100644 --- a/frontend/src/store/modules/browser.js +++ b/frontend/src/store/modules/browser.js @@ -59,9 +59,12 @@ const state = { filterMode: "base", browseLoaded: false, librariesExist: null, - packageVersion: process.env.VUE_APP_PACKAGE_VERSION, scanNotify: false, numPages: 1, + versions: { + installed: process.env.VUE_APP_PACKAGE_VERSION, + latest: undefined, + }, }; const isRootGroupEnabled = (state, rootGroup) => { @@ -95,6 +98,9 @@ const mutations = { setBrowseRoute(state, route) { state.routes.current = route; }, + setVersions(state, versions) { + state.versions = versions; + }, setSettings(state, data) { if (!data) { console.warn("no settings data! ${data}"); @@ -293,6 +299,7 @@ const actions = { await API.getBrowseOpened(route) .then((response) => { const data = response.data; + commit("setVersions", data.versions); commit("setSettings", data.settings); if (!validateState({ state, commit, dispatch })) { // will have dispatched to SetSetting if fails. diff --git a/poetry.lock b/poetry.lock index b0f9b349d..f09fdfe5a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -132,6 +132,14 @@ version = "1.14.2" [package.dependencies] pycparser = "*" +[[package]] +category = "main" +description = "Universal encoding detector for Python 2 and 3" +name = "chardet" +optional = false +python-versions = "*" +version = "3.0.4" + [[package]] category = "dev" description = "Composable command line interface toolkit" @@ -426,6 +434,14 @@ optional = false python-versions = "*" version = "5.2.0" +[[package]] +category = "main" +description = "Internationalized Domain Names in Applications (IDNA)" +name = "idna" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.10" + [[package]] category = "dev" description = "Read metadata from Python packages" @@ -910,6 +926,24 @@ optional = false python-versions = "*" version = "2020.7.14" +[[package]] +category = "main" +description = "Python HTTP for Humans." +name = "requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "2.24.0" + +[package.dependencies] +certifi = ">=2017.4.17" +chardet = ">=3.0.2,<4" +idna = ">=2.5,<3" +urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26" + +[package.extras] +security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] +socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7)", "win-inet-pton"] + [[package]] category = "main" description = "Simple, fast, extensible JSON encoder/decoder for Python" @@ -994,6 +1028,19 @@ version = "0.6.0" mypy-extensions = ">=0.3.0" typing-extensions = ">=3.7.4" +[[package]] +category = "main" +description = "HTTP library with thread-safe connection pooling, file post, and more." +name = "urllib3" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +version = "1.25.10" + +[package.extras] +brotli = ["brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)", "ipaddress"] +socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] + [[package]] category = "dev" description = "Find dead code" @@ -1071,7 +1118,7 @@ docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] testing = ["jaraco.itertools", "func-timeout"] [metadata] -content-hash = "f0bb9db4a382b3637e3617074ff4028af8e60771fa515edfdccdb781a1ead313" +content-hash = "6510b7a0e53c982880cd50f21d13d762ac4cf774efa4c255d9666141e5076e5a" lock-version = "1.0" python-versions = "^3.7" @@ -1189,6 +1236,10 @@ cffi = [ {file = "cffi-1.14.2-cp38-cp38-win_amd64.whl", hash = "sha256:12a453e03124069b6896107ee133ae3ab04c624bb10683e1ed1c1663df17c13c"}, {file = "cffi-1.14.2.tar.gz", hash = "sha256:ae8f34d50af2c2154035984b8b5fc5d9ed63f32fe615646ab435b05b132ca91b"}, ] +chardet = [ + {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, + {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, +] click = [ {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, @@ -1348,6 +1399,10 @@ hyperframe = [ {file = "hyperframe-5.2.0-py2.py3-none-any.whl", hash = "sha256:5187962cb16dcc078f23cb5a4b110098d546c3f41ff2d4038a9896893bbd0b40"}, {file = "hyperframe-5.2.0.tar.gz", hash = "sha256:a9f5c17f2cc3c719b917c4f33ed1c61bd1f8dfac4b1bd23b7c80b3400971b41f"}, ] +idna = [ + {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, + {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, +] importlib-metadata = [ {file = "importlib_metadata-1.7.0-py2.py3-none-any.whl", hash = "sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070"}, {file = "importlib_metadata-1.7.0.tar.gz", hash = "sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83"}, @@ -1625,6 +1680,10 @@ regex = [ {file = "regex-2020.7.14-cp38-cp38-win_amd64.whl", hash = "sha256:7a2dd66d2d4df34fa82c9dc85657c5e019b87932019947faece7983f2089a840"}, {file = "regex-2020.7.14.tar.gz", hash = "sha256:3a3af27a8d23143c49a3420efe5b3f8cf1a48c6fc8bc6856b03f638abc1833bb"}, ] +requests = [ + {file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"}, + {file = "requests-2.24.0.tar.gz", hash = "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"}, +] simplejson = [ {file = "simplejson-3.17.2-cp27-cp27m-macosx_10_13_x86_64.whl", hash = "sha256:2d3eab2c3fe52007d703a26f71cf649a8c771fcdd949a3ae73041ba6797cfcf8"}, {file = "simplejson-3.17.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:813846738277729d7db71b82176204abc7fdae2f566e2d9fcf874f9b6472e3e6"}, @@ -1735,6 +1794,10 @@ typing-inspect = [ {file = "typing_inspect-0.6.0-py3-none-any.whl", hash = "sha256:3b98390df4d999a28cf5b35d8b333425af5da2ece8a4ea9e98f71e7591347b4f"}, {file = "typing_inspect-0.6.0.tar.gz", hash = "sha256:8f1b1dd25908dbfd81d3bebc218011531e7ab614ba6e5bf7826d887c834afab7"}, ] +urllib3 = [ + {file = "urllib3-1.25.10-py2.py3-none-any.whl", hash = "sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461"}, + {file = "urllib3-1.25.10.tar.gz", hash = "sha256:91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a"}, +] vulture = [ {file = "vulture-2.1-py2.py3-none-any.whl", hash = "sha256:f4b3a422a6cb0285ec9df0ed46241a8577fa53ec3c43f8c70bd2a4d708c95377"}, {file = "vulture-2.1.tar.gz", hash = "sha256:933bf7f3848e9e39ecab6a12faa59d5185471c887534abac13baea6fe8138cc2"}, diff --git a/pyproject.toml b/pyproject.toml index cc7c15b47..2bf8456ac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,6 +45,7 @@ regex = "^2020.4.4" watchdog = "^0.10" websocket_client = "^0.57.0" whitenoise = { extras = ["brotli"], version = "^5.2.0" } +requests = "^2.24.0" [tool.poetry.dev-dependencies] black = "^20.8b1" From 941db5150c4500f8fa7f77bc0a4ab2560f30b433 Mon Sep 17 00:00:00 2001 From: AJ Slater Date: Tue, 15 Sep 2020 20:14:09 -0700 Subject: [PATCH 039/528] Squashed commit of the following: commit 6001d4a338bf9dc86238b0da565e76a891d3de02 Author: AJ Slater Date: Tue Sep 15 19:55:53 2020 -0700 remove the init_admin_flags from migrations commit 38556ea04959e02522c08288c152f61ea18b7a3a Author: AJ Slater Date: Tue Sep 15 19:47:38 2020 -0700 minor cleanups and comments commit 3e40d41c52b188353b0d04e96c7e35dec5315d95 Author: AJ Slater Date: Tue Sep 15 19:31:46 2020 -0700 bump news commit 1321826d522c32cb62a13abb1ea3df8173f8cf3d Author: AJ Slater Date: Tue Sep 15 18:00:20 2020 -0700 add dev config dir to prettierignore commit 784e165efc57f6f97092e8d17236a0bde40b226d Author: AJ Slater Date: Tue Sep 15 17:52:09 2020 -0700 disable session users first try --- .prettierignore | 1 + Dockerfile | 4 +- NEWS | 1 + codex/librarian/importer.py | 1 - codex/migrations/0001_init.py | 10 -- codex/models.py | 3 +- codex/run.py | 9 ++ codex/serializers/auth.py | 13 +- codex/settings.py | 6 +- codex/views/auth.py | 35 ++++- codex/views/browse_choices.py | 3 + codex/views/browser.py | 8 +- codex/views/metadata.py | 6 + codex/views/reader.py | 2 + codex/views/scan_notify.py | 3 + codex/websocket_server.py | 1 + frontend/src/browser.vue | 75 ++++++---- frontend/src/reader.vue | 217 +++++++++++++++-------------- frontend/src/store/modules/auth.js | 16 ++- 19 files changed, 261 insertions(+), 153 deletions(-) diff --git a/.prettierignore b/.prettierignore index 12cae97df..496404879 100644 --- a/.prettierignore +++ b/.prettierignore @@ -5,6 +5,7 @@ __pycache__ codex/static_build codex/static_root +/config frontend/dist frontend/public/css/normalize.css static_prod diff --git a/Dockerfile b/Dockerfile index 9a0cf65da..6e60bcab1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,11 +2,11 @@ ARG INSTALL_BASE_VERSION ARG RUNNABLE_BASE_VERSION FROM ajslater/codex-install-base:${INSTALL_BASE_VERSION} AS codex-install -COPY dist/*.whl /tmp/ +ARG PKG_VERSION +COPY dist/codex-${PKG_VERSION}*.whl /tmp/ RUN pip3 wheel /tmp/*.whl --wheel-dir=/wheels FROM ajslater/codex-base:${RUNNABLE_BASE_VERSION} -ARG PKG_VERSION LABEL version v${PKG_VERSION} RUN echo "*** install python wheels ***" diff --git a/NEWS b/NEWS index 095beca3e..9356340f7 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ v0.5.12 * admin page for failed imports * snackbar tells admins when scans are happening * report the latest version available in the browser footer tooltip +* admin flag for disabling codex for non-users v0.5.11 * browser rows now adapt to browse tile size diff --git a/codex/librarian/importer.py b/codex/librarian/importer.py index b768b77f1..b6dfcc0a8 100644 --- a/codex/librarian/importer.py +++ b/codex/librarian/importer.py @@ -321,7 +321,6 @@ def import_metadata(self): self.md["series"], self.md["volume"], ) = self.get_browse_containers() - # TODO Should this be just a library id? library = Library.objects.only("pk", "path").get(pk=self.library_id) self.set_locales() credits = self.get_credits() diff --git a/codex/migrations/0001_init.py b/codex/migrations/0001_init.py index a1a027f7a..ee9666a0a 100644 --- a/codex/migrations/0001_init.py +++ b/codex/migrations/0001_init.py @@ -11,13 +11,6 @@ import codex.models -def init_admin_flags(apps, schema_editor): - """Initalize the admin flag rows""" - # AdminFlag = apps.get_model("codex", "AdminFlag") # noqa N806 - for name in codex.models.AdminFlag.FLAG_NAMES: - codex.models.AdminFlag.objects.update_or_create(name=name) - - class Migration(migrations.Migration): initial = True @@ -667,7 +660,4 @@ class Migration(migrations.Migration): "unique_together": {("user", "session", "comic")}, }, ), - migrations.RunPython( - code=init_admin_flags, - ), ] diff --git a/codex/models.py b/codex/models.py index 2d4758752..720205f7b 100644 --- a/codex/models.py +++ b/codex/models.py @@ -392,7 +392,8 @@ class AdminFlag(NamedModel): ENABLE_FOLDER_VIEW = "Enable Folder View" ENABLE_REGISTRATION = "Enable Registration" - FLAG_NAMES = (ENABLE_FOLDER_VIEW, ENABLE_REGISTRATION) + ENABLE_NON_USERS = "Enable Non Users" + FLAG_NAMES = (ENABLE_FOLDER_VIEW, ENABLE_REGISTRATION, ENABLE_NON_USERS) on = BooleanField(default=True) diff --git a/codex/run.py b/codex/run.py index 796b2f3d4..880cebc90 100755 --- a/codex/run.py +++ b/codex/run.py @@ -15,6 +15,7 @@ from codex.asgi import application from codex.librarian.librariand import PORT +from codex.models import AdminFlag from codex.models import Library from codex.settings import CODEX_PATH from codex.settings import CONFIG_PATH @@ -59,6 +60,13 @@ def ensure_superuser(): LOG.info(f"{prefix}ated admin user.") +def init_admin_flags(): + """Initalize the admin flag rows""" + # AdminFlag = apps.get_model("codex", "AdminFlag") # noqa N806 + for name in AdminFlag.FLAG_NAMES: + AdminFlag.objects.get_or_create(name=name) + + def unset_scan_in_progress(): stuck_libraries = Library.objects.filter(scan_in_progress=True).only( "scan_in_progress", "path" @@ -74,6 +82,7 @@ def setup_db(): django.setup() update_db() ensure_superuser() + init_admin_flags() unset_scan_in_progress() diff --git a/codex/serializers/auth.py b/codex/serializers/auth.py index c7c34226e..9636a2440 100644 --- a/codex/serializers/auth.py +++ b/codex/serializers/auth.py @@ -5,16 +5,27 @@ from rest_framework.fields import CharField from rest_framework.serializers import ModelSerializer from rest_framework.serializers import Serializer +from rest_framework.serializers import SerializerMethodField + +from codex.models import AdminFlag class UserSerializer(ModelSerializer): """Serialize User model for UI.""" + enableNonUsers = SerializerMethodField() # noqa: N815 + + def get_enableNonUsers(self, obj): # noqa: N802 + """Piggyback on user objects.""" + # XXX Maybe should be its own view. + enu_flag = AdminFlag.objects.only("on").get(name=AdminFlag.ENABLE_NON_USERS) + return enu_flag.on + class Meta: """Model spec.""" model = User - fields = ("pk", "username", "is_staff") + fields = ("pk", "username", "is_staff", "enableNonUsers") read_only_fields = fields diff --git a/codex/settings.py b/codex/settings.py index 201342f12..b0d1a14fb 100644 --- a/codex/settings.py +++ b/codex/settings.py @@ -199,9 +199,11 @@ except Exception: LOG.warn("Couldn't find hypercorn config to check static root path.") ROOT_PATH = "" -CONFIG_STATIC = CONFIG_PATH / "static" # XXX A little dangerous +CONFIG_STATIC = CONFIG_PATH / "static" CONFIG_STATIC.mkdir(exist_ok=True, parents=True) -# Abuse the Whitenoise ROOT feature to serve covers +# XXX Abuse the Whitenoise ROOT feature to serve covers +# A little dangerous because whitenoise will serve anything from that +# static directory. But it sure is fast. WHITENOISE_ROOT = CONFIG_STATIC WHITENOISE_KEEP_ONLY_HASHED_FILES = True WHITENOISE_STATIC_PREFIX = "static/" diff --git a/codex/views/auth.py b/codex/views/auth.py index 5b7b4f7eb..34c5ca7d5 100644 --- a/codex/views/auth.py +++ b/codex/views/auth.py @@ -22,6 +22,7 @@ LOG = logging.getLogger(__name__) +NULL_USER = {"pk": None, "username": None, "is_staff": False} def set_timezone(request, serializer): @@ -30,9 +31,34 @@ def set_timezone(request, serializer): request.session.save() +class IsAuthenticatedOrEnabledNonUsers(IsAuthenticated): + """Custom DRF Authentication class.""" + + def has_permission(self, request, view): + """True if ENABLE_NON_USERS is true or user is authenticated.""" + enu_flag = AdminFlag.objects.only("on").get(name=AdminFlag.ENABLE_NON_USERS) + if enu_flag.on: + return True + return super().has_permission(request, view) + + +class RegisterViewPermission(IsAuthenticatedOrEnabledNonUsers): + """Custom Authentictiaon that always allows GET.""" + + SAFE_METHODS = ("GET", "HEAD", "OPTIONS") + + def has_permission(self, request, view): + """GET is always good.""" + if request.method in self.SAFE_METHODS: + return True + return super().has_permission(request, view) + + class RegisterView(APIView): """Create a user.""" + permission_classes = [RegisterViewPermission] + def create(self, username, password): """Create the user and assign the session bookmarks to the user.""" user = User(username=username) @@ -109,14 +135,17 @@ def post(self, request, *args, **kwargs): class UserView(APIView): """User info.""" - permission_classes = [IsAuthenticated] - def post(self, request, *args, **kwargs): """Get the user info for the current user.""" serializer = TimezoneSerializer(data=self.request.data) serializer.is_valid() set_timezone(request, serializer) - serializer = UserSerializer(self.request.user) + + user = self.request.user + if not user: + user = NULL_USER + + serializer = UserSerializer(user) return Response(serializer.data) diff --git a/codex/views/browse_choices.py b/codex/views/browse_choices.py index 736d3841f..6cab4d8f6 100644 --- a/codex/views/browse_choices.py +++ b/codex/views/browse_choices.py @@ -8,6 +8,7 @@ from codex.models import Comic from codex.serializers.vuetify import VueIntChoiceSerializer +from codex.views.auth import IsAuthenticatedOrEnabledNonUsers from codex.views.browse_base import BrowseBaseView @@ -17,6 +18,8 @@ class BrowseChoiceView(BrowseBaseView): """Get choices for filter dialog.""" + permission_classes = [IsAuthenticatedOrEnabledNonUsers] + def get(self, request, *args, **kwargs): """Get choices for filter dialog.""" choice_type = self.kwargs.get("choice_type") diff --git a/codex/views/browser.py b/codex/views/browser.py index d5aa8a44b..7a5b5312c 100644 --- a/codex/views/browser.py +++ b/codex/views/browser.py @@ -39,6 +39,7 @@ from codex.serializers.browse import BrowserOpenedSerializer from codex.serializers.browse import BrowserSettingsSerializer from codex.settings import CACHE_PATH +from codex.views.auth import IsAuthenticatedOrEnabledNonUsers from codex.views.browse_base import BrowseBaseView from codex.views.mixins import UserBookmarkMixin @@ -50,6 +51,8 @@ class BrowseView(BrowseBaseView, UserBookmarkMixin): """Browse comics with a variety of filters and sorts.""" + permission_classes = [IsAuthenticatedOrEnabledNonUsers] + COMIC_GROUP = "c" GROUP_MODEL = bidict( { @@ -456,7 +459,10 @@ def raise_valid_route(self, message): def validate_folder_settings(self): """Check that all the view variables for folder mode are set right.""" - if not AdminFlag.objects.only("on").get(name=AdminFlag.ENABLE_FOLDER_VIEW).on: + enable_folder_view = ( + AdminFlag.objects.only("on").get(name=AdminFlag.ENABLE_FOLDER_VIEW).on + ) + if not enable_folder_view: self.valid_nav_groups = self.get_valid_nav_groups() raise self.raise_valid_route("folder view disabled") diff --git a/codex/views/metadata.py b/codex/views/metadata.py index d84537ec6..06f16b00f 100644 --- a/codex/views/metadata.py +++ b/codex/views/metadata.py @@ -14,6 +14,7 @@ from codex.models import Comic from codex.serializers.metadata import ComicSerializer from codex.serializers.metadata import UserBookmarkFinishedSerializer +from codex.views.auth import IsAuthenticatedOrEnabledNonUsers from codex.views.browser import BrowseView from codex.views.mixins import SessionMixin from codex.views.mixins import UserBookmarkMixin @@ -25,6 +26,8 @@ class ComicDownloadView(APIView): """Return the comic archive file as an attachment.""" + permission_classes = [IsAuthenticatedOrEnabledNonUsers] + def get(self, request, *args, **kwargs): """Download a comic archive.""" pk = kwargs.get("pk") @@ -40,6 +43,8 @@ def get(self, request, *args, **kwargs): class UserBookmarkFinishedView(APIView, SessionMixin, UserBookmarkMixin): """Mark read or unread recursively.""" + permission_classes = [IsAuthenticatedOrEnabledNonUsers] + def patch(self, request, *args, **kwargs): """Mark read or unread recursively.""" serializer = UserBookmarkFinishedSerializer(data=request.data) @@ -63,6 +68,7 @@ def patch(self, request, *args, **kwargs): class ComicMetadataView(APIView, SessionMixin, UserBookmarkMixin): """Comic metadata.""" + permission_classes = [IsAuthenticatedOrEnabledNonUsers] queryset = Comic.objects.all() def get(self, request, *args, **kwargs): diff --git a/codex/views/reader.py b/codex/views/reader.py index 279942ae0..b1dc778b0 100644 --- a/codex/views/reader.py +++ b/codex/views/reader.py @@ -12,6 +12,7 @@ from codex.models import Comic from codex.serializers.read import ComicReaderInfoSerializer from codex.serializers.read import ComicReaderSettingsSerializer +from codex.views.auth import IsAuthenticatedOrEnabledNonUsers from codex.views.mixins import SessionMixin from codex.views.mixins import UserBookmarkMixin @@ -26,6 +27,7 @@ class ComicOpenedView(APIView, SessionMixin, UserBookmarkMixin): """Get info for displaying comic pages.""" + permission_classes = [IsAuthenticatedOrEnabledNonUsers] SETTINGS_KEYS = ("fit_to", "two_pages") def get_settings(self): diff --git a/codex/views/scan_notify.py b/codex/views/scan_notify.py index 70fb3baac..fc401a269 100644 --- a/codex/views/scan_notify.py +++ b/codex/views/scan_notify.py @@ -7,6 +7,7 @@ from codex.librarian.queue import QUEUE from codex.models import Library from codex.serializers.browse import ScanNotifySerializer +from codex.views.auth import IsAuthenticatedOrEnabledNonUsers LOG = logging.getLogger(__name__) @@ -16,6 +17,8 @@ class ScanNotifyView(APIView): """API endpoint for the scan notifier.""" + permission_classes = [IsAuthenticatedOrEnabledNonUsers] + @cache_control(max_age=MIN_SCAN_WAIT) def get(self, request, *args, **kwargs): """Return if any libraries are scanning.""" diff --git a/codex/websocket_server.py b/codex/websocket_server.py index 6821af87c..f0758c3ab 100644 --- a/codex/websocket_server.py +++ b/codex/websocket_server.py @@ -59,6 +59,7 @@ async def websocket_application(scope, receive, send): event = await receive() if event["type"] == "websocket.connect": + # XXX could do an auth here and figure out who's an admin. BROADCAST_CONNS.add(send) await send(WS_ACCEPT_MSG) diff --git a/frontend/src/browser.vue b/frontend/src/browser.vue index f6c6be051..77a933be6 100644 --- a/frontend/src/browser.vue +++ b/frontend/src/browser.vue @@ -2,7 +2,7 @@
- + @@ -226,11 +246,12 @@ import { mdiArrowUp, mdiCloseCircle, mdiDotsVertical } from "@mdi/js"; import { mapGetters, mapState } from "vuex"; import { ADMIN_URL } from "@/api/auth"; -import { getSocket } from "@/api/browser"; +import { FAILED_IMPORT_URL, getSocket } from "@/api/browser"; +import { getVolumeName } from "@/comic-name"; import AuthDialog from "@/components/auth-dialog"; import BrowseCard from "@/components/browse-card"; import FilterSubMenu from "@/components/filter-sub-menu"; -import PlaceholderLoading from "@/components/placeholder-loading.vue"; +import PlaceholderLoading from "@/components/placeholder-loading"; export default { name: "Browser", @@ -246,6 +267,8 @@ export default { mdiDotsVertical, socket: undefined, adminURL: ADMIN_URL, + failedImportsNotify: false, + failedImportURL: FAILED_IMPORT_URL, }; }, computed: { @@ -276,6 +299,27 @@ export default { (!this.browseLoaded && this.isOpenToSee) ); }, + longBrowseTitle: function () { + let browseTitle; + const group = this.$route.params.group; + if (+this.$route.params.pk === 0) { + browseTitle = this.browseTitle.groupName; + } else if (group === "v") { + const { parentName, groupName, groupCount } = this.browseTitle; + const volumeName = getVolumeName(groupName); + browseTitle = ""; + if (parentName) { + browseTitle += `${parentName} `; + } + browseTitle += `${volumeName}`; + if (this.browseTitle.volumeCount) { + browseTitle += ` of ${groupCount}`; + } + } else { + browseTitle = this.browseTitle.groupName; + } + return browseTitle; + }, outdated: function () { return this.versions.latest > this.versions.installed; }, @@ -410,18 +454,28 @@ export default { methods: { connectToServer: function () { if (!this.isOpenToSee) { + if (this.socket) { + this.socket.close(); + } return; } this.$store.dispatch("browser/browseOpened", this.$route.params); - this.socket = getSocket(); + this.socket = getSocket(this.isAdmin); this.socket.addEventListener("message", this.websocketListener); }, websocketListener: function (event) { console.debug("websocket push:", event.data); if (event.data === "libraryChanged") { this.$store.dispatch("browser/getBrowseObjects"); - } else if (this.isAdmin && event.data === "scanLibrary") { - this.setScanNotify(true); + } else if (this.isAdmin) { + if (event.data === "scanLibrary") { + this.setScanNotify(true); + } else if (["scanDone", "failedImports"].includes(event.data)) { + this.setScanNotify(false); + if (event.data === "failedImports") { + this.failedImportsNotify = true; + } + } } }, settingChanged: function (data) { @@ -547,6 +601,12 @@ export default { font-style: italic; } +#failedImportsNotify { +} +#failedImportsNotify a { + padding-right: 0.5em; +} + @import "~vuetify/src/styles/styles.sass"; @media #{map-get($display-breakpoints, 'sm-and-down')} { #noComicsFound { diff --git a/frontend/src/choices/browserChoices.json b/frontend/src/choices/browserChoices.json index cb855a852..d6900b3d4 100644 --- a/frontend/src/choices/browserChoices.json +++ b/frontend/src/choices/browserChoices.json @@ -9,7 +9,7 @@ { "text": "Imprints", "value": "p", "default": true }, { "text": "Series", "value": "i" }, { "text": "Volumes", "value": "s" }, - { "text": "Comics", "value": "v" }, + { "text": "Issues", "value": "v" }, { "text": "Folder View", "value": "f" } ], "settingsGroup": [ diff --git a/frontend/src/store/modules/browser.js b/frontend/src/store/modules/browser.js index d1804e8de..85e80274e 100644 --- a/frontend/src/store/modules/browser.js +++ b/frontend/src/store/modules/browser.js @@ -54,7 +54,11 @@ const state = { enableFolderView: true, }, }, - browseTitle: "", + browseTitle: { + parentName: undefined, + groupName: undefined, + groupCount: undefined, + }, objList: [], filterMode: "base", browseLoaded: false, diff --git a/poetry.lock b/poetry.lock index f09fdfe5a..85cffd51c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -127,7 +127,7 @@ description = "Foreign Function Interface for Python calling C code." name = "cffi" optional = false python-versions = "*" -version = "1.14.2" +version = "1.14.3" [package.dependencies] pycparser = "*" @@ -191,7 +191,7 @@ description = "Code coverage measurement for Python" name = "coverage" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" -version = "5.2.1" +version = "5.3" [package.dependencies] [package.dependencies.toml] @@ -739,7 +739,7 @@ description = "Python client to neovim" name = "pynvim" optional = false python-versions = "*" -version = "0.4.1" +version = "0.4.2" [package.dependencies] greenlet = "*" @@ -772,7 +772,7 @@ description = "pytest: simple powerful testing with Python" name = "pytest" optional = false python-versions = ">=3.5" -version = "6.0.1" +version = "6.0.2" [package.dependencies] atomicwrites = ">=1.0" @@ -830,7 +830,7 @@ description = "A Django plugin for pytest." name = "pytest-django" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "3.9.0" +version = "3.10.0" [package.dependencies] pytest = ">=3.6" @@ -899,10 +899,9 @@ description = "Code Metrics in Python" name = "radon" optional = false python-versions = "*" -version = "4.2.0" +version = "4.3.1" [package.dependencies] -flake8-polyfill = "*" future = "*" mando = ">=0.6,<0.7" @@ -910,6 +909,9 @@ mando = ">=0.6,<0.7" python = ">=3.5" version = ">=0.4.1" +[package.extras] +flake8 = ["flake8-polyfill"] + [[package]] category = "main" description = "RAR archive reader for Python" @@ -1207,34 +1209,42 @@ certifi = [ {file = "certifi-2020.6.20.tar.gz", hash = "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3"}, ] cffi = [ - {file = "cffi-1.14.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:da9d3c506f43e220336433dffe643fbfa40096d408cb9b7f2477892f369d5f82"}, - {file = "cffi-1.14.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:23e44937d7695c27c66a54d793dd4b45889a81b35c0751ba91040fe825ec59c4"}, - {file = "cffi-1.14.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:0da50dcbccd7cb7e6c741ab7912b2eff48e85af217d72b57f80ebc616257125e"}, - {file = "cffi-1.14.2-cp27-cp27m-win32.whl", hash = "sha256:76ada88d62eb24de7051c5157a1a78fd853cca9b91c0713c2e973e4196271d0c"}, - {file = "cffi-1.14.2-cp27-cp27m-win_amd64.whl", hash = "sha256:15a5f59a4808f82d8ec7364cbace851df591c2d43bc76bcbe5c4543a7ddd1bf1"}, - {file = "cffi-1.14.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:e4082d832e36e7f9b2278bc774886ca8207346b99f278e54c9de4834f17232f7"}, - {file = "cffi-1.14.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:57214fa5430399dffd54f4be37b56fe22cedb2b98862550d43cc085fb698dc2c"}, - {file = "cffi-1.14.2-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:6843db0343e12e3f52cc58430ad559d850a53684f5b352540ca3f1bc56df0731"}, - {file = "cffi-1.14.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:577791f948d34d569acb2d1add5831731c59d5a0c50a6d9f629ae1cefd9ca4a0"}, - {file = "cffi-1.14.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:8662aabfeab00cea149a3d1c2999b0731e70c6b5bac596d95d13f643e76d3d4e"}, - {file = "cffi-1.14.2-cp35-cp35m-win32.whl", hash = "sha256:837398c2ec00228679513802e3744d1e8e3cb1204aa6ad408b6aff081e99a487"}, - {file = "cffi-1.14.2-cp35-cp35m-win_amd64.whl", hash = "sha256:bf44a9a0141a082e89c90e8d785b212a872db793a0080c20f6ae6e2a0ebf82ad"}, - {file = "cffi-1.14.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:29c4688ace466a365b85a51dcc5e3c853c1d283f293dfcc12f7a77e498f160d2"}, - {file = "cffi-1.14.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:99cc66b33c418cd579c0f03b77b94263c305c389cb0c6972dac420f24b3bf123"}, - {file = "cffi-1.14.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:65867d63f0fd1b500fa343d7798fa64e9e681b594e0a07dc934c13e76ee28fb1"}, - {file = "cffi-1.14.2-cp36-cp36m-win32.whl", hash = "sha256:f5033952def24172e60493b68717792e3aebb387a8d186c43c020d9363ee7281"}, - {file = "cffi-1.14.2-cp36-cp36m-win_amd64.whl", hash = "sha256:7057613efefd36cacabbdbcef010e0a9c20a88fc07eb3e616019ea1692fa5df4"}, - {file = "cffi-1.14.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6539314d84c4d36f28d73adc1b45e9f4ee2a89cdc7e5d2b0a6dbacba31906798"}, - {file = "cffi-1.14.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:672b539db20fef6b03d6f7a14b5825d57c98e4026401fce838849f8de73fe4d4"}, - {file = "cffi-1.14.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:95e9094162fa712f18b4f60896e34b621df99147c2cee216cfa8f022294e8e9f"}, - {file = "cffi-1.14.2-cp37-cp37m-win32.whl", hash = "sha256:b9aa9d8818c2e917fa2c105ad538e222a5bce59777133840b93134022a7ce650"}, - {file = "cffi-1.14.2-cp37-cp37m-win_amd64.whl", hash = "sha256:e4b9b7af398c32e408c00eb4e0d33ced2f9121fd9fb978e6c1b57edd014a7d15"}, - {file = "cffi-1.14.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e613514a82539fc48291d01933951a13ae93b6b444a88782480be32245ed4afa"}, - {file = "cffi-1.14.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:9b219511d8b64d3fa14261963933be34028ea0e57455baf6781fe399c2c3206c"}, - {file = "cffi-1.14.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:c0b48b98d79cf795b0916c57bebbc6d16bb43b9fc9b8c9f57f4cf05881904c75"}, - {file = "cffi-1.14.2-cp38-cp38-win32.whl", hash = "sha256:15419020b0e812b40d96ec9d369b2bc8109cc3295eac6e013d3261343580cc7e"}, - {file = "cffi-1.14.2-cp38-cp38-win_amd64.whl", hash = "sha256:12a453e03124069b6896107ee133ae3ab04c624bb10683e1ed1c1663df17c13c"}, - {file = "cffi-1.14.2.tar.gz", hash = "sha256:ae8f34d50af2c2154035984b8b5fc5d9ed63f32fe615646ab435b05b132ca91b"}, + {file = "cffi-1.14.3-2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3eeeb0405fd145e714f7633a5173318bd88d8bbfc3dd0a5751f8c4f70ae629bc"}, + {file = "cffi-1.14.3-2-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:cb763ceceae04803adcc4e2d80d611ef201c73da32d8f2722e9d0ab0c7f10768"}, + {file = "cffi-1.14.3-2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:44f60519595eaca110f248e5017363d751b12782a6f2bd6a7041cba275215f5d"}, + {file = "cffi-1.14.3-2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c53af463f4a40de78c58b8b2710ade243c81cbca641e34debf3396a9640d6ec1"}, + {file = "cffi-1.14.3-2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:33c6cdc071ba5cd6d96769c8969a0531be2d08c2628a0143a10a7dcffa9719ca"}, + {file = "cffi-1.14.3-2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c11579638288e53fc94ad60022ff1b67865363e730ee41ad5e6f0a17188b327a"}, + {file = "cffi-1.14.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:3cb3e1b9ec43256c4e0f8d2837267a70b0e1ca8c4f456685508ae6106b1f504c"}, + {file = "cffi-1.14.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:f0620511387790860b249b9241c2f13c3a80e21a73e0b861a2df24e9d6f56730"}, + {file = "cffi-1.14.3-cp27-cp27m-win32.whl", hash = "sha256:005f2bfe11b6745d726dbb07ace4d53f057de66e336ff92d61b8c7e9c8f4777d"}, + {file = "cffi-1.14.3-cp27-cp27m-win_amd64.whl", hash = "sha256:2f9674623ca39c9ebe38afa3da402e9326c245f0f5ceff0623dccdac15023e05"}, + {file = "cffi-1.14.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:09e96138280241bd355cd585148dec04dbbedb4f46128f340d696eaafc82dd7b"}, + {file = "cffi-1.14.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:3363e77a6176afb8823b6e06db78c46dbc4c7813b00a41300a4873b6ba63b171"}, + {file = "cffi-1.14.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:0ef488305fdce2580c8b2708f22d7785ae222d9825d3094ab073e22e93dfe51f"}, + {file = "cffi-1.14.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:0b1ad452cc824665ddc682400b62c9e4f5b64736a2ba99110712fdee5f2505c4"}, + {file = "cffi-1.14.3-cp35-cp35m-win32.whl", hash = "sha256:85ba797e1de5b48aa5a8427b6ba62cf69607c18c5d4eb747604b7302f1ec382d"}, + {file = "cffi-1.14.3-cp35-cp35m-win_amd64.whl", hash = "sha256:e66399cf0fc07de4dce4f588fc25bfe84a6d1285cc544e67987d22663393926d"}, + {file = "cffi-1.14.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:15f351bed09897fbda218e4db5a3d5c06328862f6198d4fb385f3e14e19decb3"}, + {file = "cffi-1.14.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4d7c26bfc1ea9f92084a1d75e11999e97b62d63128bcc90c3624d07813c52808"}, + {file = "cffi-1.14.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:23e5d2040367322824605bc29ae8ee9175200b92cb5483ac7d466927a9b3d537"}, + {file = "cffi-1.14.3-cp36-cp36m-win32.whl", hash = "sha256:a624fae282e81ad2e4871bdb767e2c914d0539708c0f078b5b355258293c98b0"}, + {file = "cffi-1.14.3-cp36-cp36m-win_amd64.whl", hash = "sha256:de31b5164d44ef4943db155b3e8e17929707cac1e5bd2f363e67a56e3af4af6e"}, + {file = "cffi-1.14.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f92cdecb618e5fa4658aeb97d5eb3d2f47aa94ac6477c6daf0f306c5a3b9e6b1"}, + {file = "cffi-1.14.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:22399ff4870fb4c7ef19fff6eeb20a8bbf15571913c181c78cb361024d574579"}, + {file = "cffi-1.14.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:f4eae045e6ab2bb54ca279733fe4eb85f1effda392666308250714e01907f394"}, + {file = "cffi-1.14.3-cp37-cp37m-win32.whl", hash = "sha256:b0358e6fefc74a16f745afa366acc89f979040e0cbc4eec55ab26ad1f6a9bfbc"}, + {file = "cffi-1.14.3-cp37-cp37m-win_amd64.whl", hash = "sha256:6642f15ad963b5092d65aed022d033c77763515fdc07095208f15d3563003869"}, + {file = "cffi-1.14.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:2791f68edc5749024b4722500e86303a10d342527e1e3bcac47f35fbd25b764e"}, + {file = "cffi-1.14.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:529c4ed2e10437c205f38f3691a68be66c39197d01062618c55f74294a4a4828"}, + {file = "cffi-1.14.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8f0f1e499e4000c4c347a124fa6a27d37608ced4fe9f7d45070563b7c4c370c9"}, + {file = "cffi-1.14.3-cp38-cp38-win32.whl", hash = "sha256:3b8eaf915ddc0709779889c472e553f0d3e8b7bdf62dab764c8921b09bf94522"}, + {file = "cffi-1.14.3-cp38-cp38-win_amd64.whl", hash = "sha256:bbd2f4dfee1079f76943767fce837ade3087b578aeb9f69aec7857d5bf25db15"}, + {file = "cffi-1.14.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:cc75f58cdaf043fe6a7a6c04b3b5a0e694c6a9e24050967747251fb80d7bce0d"}, + {file = "cffi-1.14.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:bf39a9e19ce7298f1bd6a9758fa99707e9e5b1ebe5e90f2c3913a47bc548747c"}, + {file = "cffi-1.14.3-cp39-cp39-win32.whl", hash = "sha256:d80998ed59176e8cba74028762fbd9b9153b9afc71ea118e63bbf5d4d0f9552b"}, + {file = "cffi-1.14.3-cp39-cp39-win_amd64.whl", hash = "sha256:c150eaa3dadbb2b5339675b88d4573c1be3cb6f2c33a6c83387e10cc0bf05bd3"}, + {file = "cffi-1.14.3.tar.gz", hash = "sha256:f92f789e4f9241cd262ad7a555ca2c648a98178a953af117ef7fad46aa1d5591"}, ] chardet = [ {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, @@ -1257,40 +1267,40 @@ comicbox = [ {file = "comicbox-0.1.4.tar.gz", hash = "sha256:12fb5ce7e202a03687cda0d854496d6170d0cfd50cc195dbfb04db935ada6742"}, ] coverage = [ - {file = "coverage-5.2.1-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:40f70f81be4d34f8d491e55936904db5c527b0711b2a46513641a5729783c2e4"}, - {file = "coverage-5.2.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:675192fca634f0df69af3493a48224f211f8db4e84452b08d5fcebb9167adb01"}, - {file = "coverage-5.2.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:2fcc8b58953d74d199a1a4d633df8146f0ac36c4e720b4a1997e9b6327af43a8"}, - {file = "coverage-5.2.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:64c4f340338c68c463f1b56e3f2f0423f7b17ba6c3febae80b81f0e093077f59"}, - {file = "coverage-5.2.1-cp27-cp27m-win32.whl", hash = "sha256:52f185ffd3291196dc1aae506b42e178a592b0b60a8610b108e6ad892cfc1bb3"}, - {file = "coverage-5.2.1-cp27-cp27m-win_amd64.whl", hash = "sha256:30bc103587e0d3df9e52cd9da1dd915265a22fad0b72afe54daf840c984b564f"}, - {file = "coverage-5.2.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:9ea749fd447ce7fb1ac71f7616371f04054d969d412d37611716721931e36efd"}, - {file = "coverage-5.2.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ce7866f29d3025b5b34c2e944e66ebef0d92e4a4f2463f7266daa03a1332a651"}, - {file = "coverage-5.2.1-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:4869ab1c1ed33953bb2433ce7b894a28d724b7aa76c19b11e2878034a4e4680b"}, - {file = "coverage-5.2.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:a3ee9c793ffefe2944d3a2bd928a0e436cd0ac2d9e3723152d6fd5398838ce7d"}, - {file = "coverage-5.2.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:28f42dc5172ebdc32622a2c3f7ead1b836cdbf253569ae5673f499e35db0bac3"}, - {file = "coverage-5.2.1-cp35-cp35m-win32.whl", hash = "sha256:e26c993bd4b220429d4ec8c1468eca445a4064a61c74ca08da7429af9bc53bb0"}, - {file = "coverage-5.2.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4186fc95c9febeab5681bc3248553d5ec8c2999b8424d4fc3a39c9cba5796962"}, - {file = "coverage-5.2.1-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:b360d8fd88d2bad01cb953d81fd2edd4be539df7bfec41e8753fe9f4456a5082"}, - {file = "coverage-5.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:1adb6be0dcef0cf9434619d3b892772fdb48e793300f9d762e480e043bd8e716"}, - {file = "coverage-5.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:098a703d913be6fbd146a8c50cc76513d726b022d170e5e98dc56d958fd592fb"}, - {file = "coverage-5.2.1-cp36-cp36m-win32.whl", hash = "sha256:962c44070c281d86398aeb8f64e1bf37816a4dfc6f4c0f114756b14fc575621d"}, - {file = "coverage-5.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1ed2bdb27b4c9fc87058a1cb751c4df8752002143ed393899edb82b131e0546"}, - {file = "coverage-5.2.1-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:c890728a93fffd0407d7d37c1e6083ff3f9f211c83b4316fae3778417eab9811"}, - {file = "coverage-5.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:538f2fd5eb64366f37c97fdb3077d665fa946d2b6d95447622292f38407f9258"}, - {file = "coverage-5.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:27ca5a2bc04d68f0776f2cdcb8bbd508bbe430a7bf9c02315cd05fb1d86d0034"}, - {file = "coverage-5.2.1-cp37-cp37m-win32.whl", hash = "sha256:aab75d99f3f2874733946a7648ce87a50019eb90baef931698f96b76b6769a46"}, - {file = "coverage-5.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:c2ff24df02a125b7b346c4c9078c8936da06964cc2d276292c357d64378158f8"}, - {file = "coverage-5.2.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:304fbe451698373dc6653772c72c5d5e883a4aadaf20343592a7abb2e643dae0"}, - {file = "coverage-5.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c96472b8ca5dc135fb0aa62f79b033f02aa434fb03a8b190600a5ae4102df1fd"}, - {file = "coverage-5.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8505e614c983834239f865da2dd336dcf9d72776b951d5dfa5ac36b987726e1b"}, - {file = "coverage-5.2.1-cp38-cp38-win32.whl", hash = "sha256:700997b77cfab016533b3e7dbc03b71d33ee4df1d79f2463a318ca0263fc29dd"}, - {file = "coverage-5.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:46794c815e56f1431c66d81943fa90721bb858375fb36e5903697d5eef88627d"}, - {file = "coverage-5.2.1-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:16042dc7f8e632e0dcd5206a5095ebd18cb1d005f4c89694f7f8aafd96dd43a3"}, - {file = "coverage-5.2.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:c1bbb628ed5192124889b51204de27c575b3ffc05a5a91307e7640eff1d48da4"}, - {file = "coverage-5.2.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:4f6428b55d2916a69f8d6453e48a505c07b2245653b0aa9f0dee38785939f5e4"}, - {file = "coverage-5.2.1-cp39-cp39-win32.whl", hash = "sha256:9e536783a5acee79a9b308be97d3952b662748c4037b6a24cbb339dc7ed8eb89"}, - {file = "coverage-5.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:b8f58c7db64d8f27078cbf2a4391af6aa4e4767cc08b37555c4ae064b8558d9b"}, - {file = "coverage-5.2.1.tar.gz", hash = "sha256:a34cb28e0747ea15e82d13e14de606747e9e484fb28d63c999483f5d5188e89b"}, + {file = "coverage-5.3-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:bd3166bb3b111e76a4f8e2980fa1addf2920a4ca9b2b8ca36a3bc3dedc618270"}, + {file = "coverage-5.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9342dd70a1e151684727c9c91ea003b2fb33523bf19385d4554f7897ca0141d4"}, + {file = "coverage-5.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:63808c30b41f3bbf65e29f7280bf793c79f54fb807057de7e5238ffc7cc4d7b9"}, + {file = "coverage-5.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4d6a42744139a7fa5b46a264874a781e8694bb32f1d76d8137b68138686f1729"}, + {file = "coverage-5.3-cp27-cp27m-win32.whl", hash = "sha256:86e9f8cd4b0cdd57b4ae71a9c186717daa4c5a99f3238a8723f416256e0b064d"}, + {file = "coverage-5.3-cp27-cp27m-win_amd64.whl", hash = "sha256:7858847f2d84bf6e64c7f66498e851c54de8ea06a6f96a32a1d192d846734418"}, + {file = "coverage-5.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:530cc8aaf11cc2ac7430f3614b04645662ef20c348dce4167c22d99bec3480e9"}, + {file = "coverage-5.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:381ead10b9b9af5f64646cd27107fb27b614ee7040bb1226f9c07ba96625cbb5"}, + {file = "coverage-5.3-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:71b69bd716698fa62cd97137d6f2fdf49f534decb23a2c6fc80813e8b7be6822"}, + {file = "coverage-5.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1d44bb3a652fed01f1f2c10d5477956116e9b391320c94d36c6bf13b088a1097"}, + {file = "coverage-5.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:1c6703094c81fa55b816f5ae542c6ffc625fec769f22b053adb42ad712d086c9"}, + {file = "coverage-5.3-cp35-cp35m-win32.whl", hash = "sha256:cedb2f9e1f990918ea061f28a0f0077a07702e3819602d3507e2ff98c8d20636"}, + {file = "coverage-5.3-cp35-cp35m-win_amd64.whl", hash = "sha256:7f43286f13d91a34fadf61ae252a51a130223c52bfefb50310d5b2deb062cf0f"}, + {file = "coverage-5.3-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:c851b35fc078389bc16b915a0a7c1d5923e12e2c5aeec58c52f4aa8085ac8237"}, + {file = "coverage-5.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:aac1ba0a253e17889550ddb1b60a2063f7474155465577caa2a3b131224cfd54"}, + {file = "coverage-5.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2b31f46bf7b31e6aa690d4c7a3d51bb262438c6dcb0d528adde446531d0d3bb7"}, + {file = "coverage-5.3-cp36-cp36m-win32.whl", hash = "sha256:c5f17ad25d2c1286436761b462e22b5020d83316f8e8fcb5deb2b3151f8f1d3a"}, + {file = "coverage-5.3-cp36-cp36m-win_amd64.whl", hash = "sha256:aef72eae10b5e3116bac6957de1df4d75909fc76d1499a53fb6387434b6bcd8d"}, + {file = "coverage-5.3-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:e8caf961e1b1a945db76f1b5fa9c91498d15f545ac0ababbe575cfab185d3bd8"}, + {file = "coverage-5.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:29a6272fec10623fcbe158fdf9abc7a5fa032048ac1d8631f14b50fbfc10d17f"}, + {file = "coverage-5.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:2d43af2be93ffbad25dd959899b5b809618a496926146ce98ee0b23683f8c51c"}, + {file = "coverage-5.3-cp37-cp37m-win32.whl", hash = "sha256:c3888a051226e676e383de03bf49eb633cd39fc829516e5334e69b8d81aae751"}, + {file = "coverage-5.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9669179786254a2e7e57f0ecf224e978471491d660aaca833f845b72a2df3709"}, + {file = "coverage-5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0203acd33d2298e19b57451ebb0bed0ab0c602e5cf5a818591b4918b1f97d516"}, + {file = "coverage-5.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:582ddfbe712025448206a5bc45855d16c2e491c2dd102ee9a2841418ac1c629f"}, + {file = "coverage-5.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:0f313707cdecd5cd3e217fc68c78a960b616604b559e9ea60cc16795c4304259"}, + {file = "coverage-5.3-cp38-cp38-win32.whl", hash = "sha256:78e93cc3571fd928a39c0b26767c986188a4118edc67bc0695bc7a284da22e82"}, + {file = "coverage-5.3-cp38-cp38-win_amd64.whl", hash = "sha256:8f264ba2701b8c9f815b272ad568d555ef98dfe1576802ab3149c3629a9f2221"}, + {file = "coverage-5.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:50691e744714856f03a86df3e2bff847c2acede4c191f9a1da38f088df342978"}, + {file = "coverage-5.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9361de40701666b034c59ad9e317bae95c973b9ff92513dd0eced11c6adf2e21"}, + {file = "coverage-5.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:c1b78fb9700fc961f53386ad2fd86d87091e06ede5d118b8a50dea285a071c24"}, + {file = "coverage-5.3-cp39-cp39-win32.whl", hash = "sha256:cb7df71de0af56000115eafd000b867d1261f786b5eebd88a0ca6360cccfaca7"}, + {file = "coverage-5.3-cp39-cp39-win_amd64.whl", hash = "sha256:47a11bdbd8ada9b7ee628596f9d97fbd3851bd9999d398e9436bd67376dbece7"}, + {file = "coverage-5.3.tar.gz", hash = "sha256:280baa8ec489c4f542f8940f9c4c2181f0306a8ee1a54eceba071a449fb870a0"}, ] cryptography = [ {file = "cryptography-3.1-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:969ae512a250f869c1738ca63be843488ff5cc031987d302c1f59c7dbe1b225f"}, @@ -1595,7 +1605,7 @@ pylsqpack = [ {file = "pylsqpack-0.3.10.tar.gz", hash = "sha256:ccf33f566e6465c3c298b74fc3644a8468db296da7b28c388a75defc29b1cc6c"}, ] pynvim = [ - {file = "pynvim-0.4.1.tar.gz", hash = "sha256:55e918d664654cfa1c9889d3dbe7c63e9f338df5d49471663f78d54c85e84c58"}, + {file = "pynvim-0.4.2.tar.gz", hash = "sha256:6bc6204d465de5888a0c5e3e783fe01988b032e22ae87875912280bef0e40f8f"}, ] pyparsing = [ {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, @@ -1607,8 +1617,8 @@ pyreadline = [ {file = "pyreadline-2.1.zip", hash = "sha256:4530592fc2e85b25b1a9f79664433da09237c1a270e4d78ea5aa3a2c7229e2d1"}, ] pytest = [ - {file = "pytest-6.0.1-py3-none-any.whl", hash = "sha256:8b6007800c53fdacd5a5c192203f4e531eb2a1540ad9c752e052ec0f7143dbad"}, - {file = "pytest-6.0.1.tar.gz", hash = "sha256:85228d75db9f45e06e57ef9bf4429267f81ac7c0d742cc9ed63d09886a9fe6f4"}, + {file = "pytest-6.0.2-py3-none-any.whl", hash = "sha256:0e37f61339c4578776e090c3b8f6b16ce4db333889d65d0efb305243ec544b40"}, + {file = "pytest-6.0.2.tar.gz", hash = "sha256:c8f57c2a30983f469bf03e68cdfa74dc474ce56b8f280ddcb080dfd91df01043"}, ] pytest-black = [ {file = "pytest-black-0.3.11.tar.gz", hash = "sha256:595eb0e7908b8a858a8564a5c8f0eae853c3926a4ec7b2afdfcedfa6fec65dd6"}, @@ -1618,8 +1628,8 @@ pytest-cov = [ {file = "pytest_cov-2.10.1-py2.py3-none-any.whl", hash = "sha256:45ec2d5182f89a81fc3eb29e3d1ed3113b9e9a873bcddb2a71faaab066110191"}, ] pytest-django = [ - {file = "pytest-django-3.9.0.tar.gz", hash = "sha256:664e5f42242e5e182519388f01b9f25d824a9feb7cd17d8f863c8d776f38baf9"}, - {file = "pytest_django-3.9.0-py2.py3-none-any.whl", hash = "sha256:64f99d565dd9497af412fcab2989fe40982c1282d4118ff422b407f3f7275ca5"}, + {file = "pytest-django-3.10.0.tar.gz", hash = "sha256:4de6dbd077ed8606616958f77655fed0d5e3ee45159475671c7fa67596c6dba6"}, + {file = "pytest_django-3.10.0-py2.py3-none-any.whl", hash = "sha256:c33e3d3da14d8409b125d825d4e74da17bb252191bf6fc3da6856e27a8b73ea4"}, ] pytest-flake8 = [ {file = "pytest-flake8-1.0.6.tar.gz", hash = "sha256:1b82bb58c88eb1db40524018d3fcfd0424575029703b4e2d8e3ee873f2b17027"}, @@ -1650,8 +1660,8 @@ pyyaml = [ {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, ] radon = [ - {file = "radon-4.2.0-py2.py3-none-any.whl", hash = "sha256:215e42c8748b5ca8ddf7c061831600b9e73e9c48770a81eeaaeeb066697aee15"}, - {file = "radon-4.2.0.tar.gz", hash = "sha256:b73f6f469c15c9616e0f7ce12080a9ecdee9f2335bdbb5ccea1f2bae26e8d20d"}, + {file = "radon-4.3.1-py2.py3-none-any.whl", hash = "sha256:29b4694ed2ceee0874661cba0ceb0174fe1ce31ee30915f672b26bc9be98cf9e"}, + {file = "radon-4.3.1.tar.gz", hash = "sha256:63a7876101a64d5418fa9acebff11f9bb48367ac79f22bf3b73c7bf430a8abc0"}, ] rarfile = [ {file = "rarfile-4.0-py3-none-any.whl", hash = "sha256:1094869119012f95c31a6f22cc3a9edbdca61861b805241116adbe2d737b68f8"}, diff --git a/pyproject.toml b/pyproject.toml index 2bf8456ac..d18b7c921 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = ["poetry.masonry.api"] [tool.poetry] name = "codex" -version = "0.5.12" +version = "0.5.13" description = "A comic archive web server." license = "GPL-2.0-only" authors = ["AJ Slater "] diff --git a/run.sh b/run.sh index 09a98a11b..c61337415 100755 --- a/run.sh +++ b/run.sh @@ -2,4 +2,5 @@ # Run the codex server cd "$(dirname "$0")" || exit 1 export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES +export PYTHONDONTWRITEBYTECODE=$DEV poetry run python3 ./codex/run.py From 696517444db2888284994d0ee1713cfa18e449b1 Mon Sep 17 00:00:00 2001 From: AJ Slater Date: Thu, 17 Sep 2020 22:01:02 -0700 Subject: [PATCH 042/528] crap i'm sure now --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index f11dc6b3f..252d9234f 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,6 @@ You will have to contact your administrator to reset your password if you forget - No intention of making this an eBook reader like [Ubooquity](https://vaemendis.net/ubooquity/). - Not interested in this becoming a sophisticated comic manager like [Mylar](https://github.com/mylar3/mylar3) -- Unsure if I want to implement a mass tag editor. ## Alternatives to Codex From fafc57e60bb8c04849a289724147eb3c144a2c7b Mon Sep 17 00:00:00 2001 From: AJ Slater Date: Fri, 25 Sep 2020 19:57:38 -0700 Subject: [PATCH 043/528] Squashed commit of the following: commit be04fac73fe3fdcd2ee600aac8106125f45bff7c Author: AJ Slater Date: Fri Sep 25 19:56:48 2020 -0700 lint commit f93023cf01b2e2f8fe0e83fdcd0c051ed1a8428e Author: AJ Slater Date: Fri Sep 25 19:55:47 2020 -0700 bump news commit 2637d430f90a382145218d691e64e28939c4f024 Author: AJ Slater Date: Fri Sep 25 19:53:27 2020 -0700 poetry and npm update commit a7d8af755fea91b202e018ce63d084dc22229daa Author: AJ Slater Date: Fri Sep 25 19:49:01 2020 -0700 add force to comic cover creation commit c6b11e3ea7866c980bc0e4b9b0772d39f81a3052 Author: AJ Slater Date: Fri Sep 25 19:25:20 2020 -0700 fix unable to delete libs commit af224ffc3b34b172ecc2ae84c848fcf1d64bf5c0 Author: AJ Slater Date: Fri Sep 25 17:08:07 2020 -0700 rehide edit button and fix issueRow layout on mobile commit 17bee0af42a14d1d53285f6ef8f4c583888a36c7 Author: AJ Slater Date: Fri Sep 25 16:50:27 2020 -0700 minor cleanup of checkbox commit c7f235af7abd00914c874b2fb65ebd1be545e1a4 Author: AJ Slater Date: Fri Sep 25 16:33:27 2020 -0700 remove comment cruft commit 073b6f08e39100aa71dc33eee6969abb473164fc Author: AJ Slater Date: Fri Sep 25 16:32:00 2020 -0700 bump version & news commit 0c8bdfb5f216df4353533d9371437caa65dfb7f7 Author: AJ Slater Date: Fri Sep 25 16:29:14 2020 -0700 dict for websocket messages commit 7a8e1e9af9bd57a93b08d9f587435ed4f47f525b Author: AJ Slater Date: Fri Sep 25 15:51:41 2020 -0700 minor cleanups commit d1ad0ef4159aade2793c424be693f4dd3d36f943 Author: AJ Slater Date: Fri Sep 25 14:01:29 2020 -0700 remove cruft commit df1d69ef2d28fd88049032d8ee7c6d21163708f6 Author: AJ Slater Date: Fri Sep 25 13:56:06 2020 -0700 minor cleanups and formalize timing for metadata commit 0e68de8a3b85bb05657b83f7d2871f02094696a0 Author: AJ Slater Date: Fri Sep 25 13:48:51 2020 -0700 two minute timeout! commit 650099da1be7510c25fb0c1ed562fdeb56a31e2c Author: AJ Slater Date: Fri Sep 25 13:15:34 2020 -0700 cleanups for metadata commit 5c06d6c8d43f3400d92bfa9062851951b0ea9981 Author: AJ Slater Date: Fri Sep 25 02:30:56 2020 -0700 progress meter for metadata commit 7775cf15f56f347136817bb1bf33f00091b13a05 Author: AJ Slater Date: Fri Sep 25 02:29:43 2020 -0700 fix no credits bug. fix pk lookup syntax commit 70688d27a01bc2eb75f8a7cce007ec2d92fbeddb Author: AJ Slater Date: Thu Sep 24 22:17:53 2020 -0700 lint commit 72b53b462cb7d5feebbe4fea6159fc3f9588fbc3 Author: AJ Slater Date: Thu Sep 24 22:17:47 2020 -0700 move comic-name into components commit f300f21097bb0d194ce1359eaf37b25c7f23ce20 Author: AJ Slater Date: Thu Sep 24 22:15:45 2020 -0700 show less metadata if not in editMode commit 7731a45e630108eae0a254d49fd009a6293e8247 Author: AJ Slater Date: Thu Sep 24 22:15:10 2020 -0700 first minort cleanups commit 30399ee10b665e39c30cef5a5332b2f31c8459f9 Author: AJ Slater Date: Thu Sep 24 18:44:54 2020 -0700 freeze the comic metadata it won't change ... yet? commit ded8672c4c0f437febcbbb0ee393cd7b056d9216 Author: AJ Slater Date: Thu Sep 24 18:44:20 2020 -0700 fix null issueChoices commit 5ecab8eb652941ff208c31cd5e1b7734a40da73f Author: AJ Slater Date: Thu Sep 24 18:44:02 2020 -0700 share initialItem across autocomplete and combobox commit 02a4e2f71c1662d6874741d025e4e10ac315f6e6 Author: AJ Slater Date: Wed Sep 23 16:21:59 2020 -0700 placeholder for metdata commit c4a4c37dee9f243626f8137dc6d5c35266dc6dbd Author: AJ Slater Date: Wed Sep 23 15:41:45 2020 -0700 Squashed commit of the following: commit 3637b056f2d2d947658767f11a5f29b8c664e817 Author: AJ Slater Date: Wed Sep 23 15:41:24 2020 -0700 fix date display and all autocompletes commit 02d14266742e64620b17787049d8d6f0594258ea Author: AJ Slater Date: Wed Sep 23 15:35:32 2020 -0700 align issues better commit 7f8efe405e883b686a10cdf8d84e0e4edd41f1fc Author: AJ Slater Date: Wed Sep 23 15:30:49 2020 -0700 fix language and country display commit 0dc983f501c421bbd223e5348abdf096337f67f4 Author: AJ Slater Date: Wed Sep 23 15:30:25 2020 -0700 wipe comic data before lookup commit fa7236f6a74e061ecb475672c72dff4de19134e0 Author: AJ Slater Date: Wed Sep 23 15:29:42 2020 -0700 fix pycountry lookup bug commit 9a6bb655e51d3f9416b5bfc3bfb2feb6ab3b72b4 Author: AJ Slater Date: Wed Sep 23 13:49:28 2020 -0700 optimize getting only the aggregate filter for metadata commit 5129983d1f589cba0acad9edbe921203645c4db4 Author: AJ Slater Date: Wed Sep 23 13:37:38 2020 -0700 compress all metdata consts into the QUERY_SERIALIZER map commit c7e35a64fd491fedbee6ba4682975a5afb54df2b Author: AJ Slater Date: Wed Sep 23 13:14:02 2020 -0700 move frontend api files to versioned directory commit 49389216c3fb60718aceb45f34fe942e46cb45fc Author: AJ Slater Date: Wed Sep 23 13:08:34 2020 -0700 rename variables. clean up cruft. comments commit 39788fc1fcce0c8ce131da1be03be2284766d386 Author: AJ Slater Date: Wed Sep 23 12:53:31 2020 -0700 lint and comments commit 3baa071e140c6f46bab63bed10bbfab13e546e5a Author: AJ Slater Date: Wed Sep 23 12:48:40 2020 -0700 lint commit 49565bc5c50c7b058e76837f8ab382db3caa63c8 Author: AJ Slater Date: Wed Sep 23 12:48:36 2020 -0700 lint ci scripts as well commit e1cac1604f0ae5e7f83fd94e9125c96c4b3104a6 Author: AJ Slater Date: Wed Sep 23 12:45:29 2020 -0700 add a progress bar to metdata commit d0e2412ae18b9a5f75f64dde1ab770e1968f1927 Author: AJ Slater Date: Wed Sep 23 12:38:21 2020 -0700 move top book cover decorations into book-cover so they display on the metadata page commit 07426ce9fdacab8c980deaebac2e913f8c3c1eba Author: AJ Slater Date: Tue Sep 22 20:55:20 2020 -0700 simpler tag icon is better commit f8e8ed39b725accffa57ba7f4978515e16a6fc4e Author: AJ Slater Date: Tue Sep 22 20:54:16 2020 -0700 Tag multiple icon commit a9a79e656cf20f141f44eb3e1b8c7b542ea27d6b Author: AJ Slater Date: Tue Sep 22 20:47:20 2020 -0700 remove log commit ee14d91ebfa3c96597003d50da2bed96351665cc Author: AJ Slater Date: Tue Sep 22 20:44:58 2020 -0700 change metadata icon commit 9b76a9bc7ca5a445d17bf505823241428588063f Author: AJ Slater Date: Tue Sep 22 20:31:11 2020 -0700 format issue decimals commit a49061082610264d7aaed1d38d1bf24f0baaddf6 Author: AJ Slater Date: Tue Sep 22 20:16:02 2020 -0700 fix issues to handle years commit 08bd7639ebca0d68cf4bff985725681be72c7dba Author: AJ Slater Date: Tue Sep 22 19:39:48 2020 -0700 credits working commit 268df3cd136972c7bc28aa7d0ea1761f4a2d24e9 Author: AJ Slater Date: Tue Sep 22 18:20:51 2020 -0700 working even better. credits, issue display and folder test remain commit a5d6d88244fb1536c840789857c7624bb8cd2c4d Author: AJ Slater Date: Mon Sep 21 19:31:49 2020 -0700 kind of working but kludgy backend solution commit 05c67e90052cc69010c20bd9d2c39d0e21745032 Author: AJ Slater Date: Fri Sep 18 16:54:50 2020 -0700 move children and page count into base class commit c0f337bcde505729380caa10a6ea665fa2d5aa38 Author: AJ Slater Date: Fri Sep 18 15:14:13 2020 -0700 move bookmark aggregation up into metadataclass for real. remove unused fit_to & two_pages commit 7c3ab1eb99e433b1181c4a3ff319329f1bd0a287 Author: AJ Slater Date: Fri Sep 18 14:08:31 2020 -0700 move bookmark annotations to browse_metadata_base --- NEWS | 6 + codex/admin.py | 4 + codex/choices/websocketMessages.json | 10 + codex/choices/websocket_messages.py | 10 + codex/librarian/cover.py | 32 +- codex/librarian/importer.py | 30 +- codex/librarian/librariand.py | 27 +- codex/librarian/queue.py | 1 + codex/serializers/browse.py | 6 +- codex/serializers/metadata.py | 179 ++++----- codex/serializers/vuetify.py | 78 +++- codex/settings.py | 2 +- codex/urls_api_v1.py | 20 +- codex/views/browse_base.py | 11 +- codex/views/browse_metadata_base.py | 167 ++++++++ codex/views/browser.py | 122 +----- codex/views/metadata.py | 321 +++++++++++++--- codex/views/mixins.py | 34 -- codex/websocket_server.py | 11 +- docker-env | 2 +- frontend/package-lock.json | 72 ++-- frontend/package.json | 12 +- frontend/src/api/{ => v1}/auth.js | 0 frontend/src/api/{ => v1}/base.js | 0 frontend/src/api/{ => v1}/browser.js | 0 frontend/src/api/{ => v1}/metadata.js | 5 +- frontend/src/api/{ => v1}/reader.js | 0 frontend/src/browser.vue | 20 +- frontend/src/choices/websocketMessages.json | 10 + frontend/src/components/auth-dialog.vue | 2 +- frontend/src/components/book-cover.vue | 103 ++++- frontend/src/components/browse-card.vue | 123 ++---- .../src/components/browse-container-menu.vue | 2 +- frontend/src/{ => components}/comic-name.js | 0 .../src/components/metadata-autocomplete.vue | 36 +- frontend/src/components/metadata-checkbox.vue | 52 +++ frontend/src/components/metadata-combobox.vue | 32 +- .../src/components/metadata-computed-items.js | 43 +++ frontend/src/components/metadata-dialog.vue | 358 ++++++++++++------ frontend/src/components/metadata-switch.vue | 2 +- frontend/src/components/metadata-tags.vue | 23 +- .../src/components/metadata-text-field.vue | 11 +- frontend/src/components/reader-comic-page.vue | 2 +- frontend/src/reader.vue | 4 +- frontend/src/router/index.js | 2 +- frontend/src/router/route.js | 12 +- frontend/src/store/modules/auth.js | 2 +- frontend/src/store/modules/browser.js | 2 +- frontend/src/store/modules/metadata.js | 9 +- frontend/src/store/modules/reader.js | 2 +- lint.sh | 2 +- poetry.lock | 147 +++---- pyproject.toml | 4 +- 53 files changed, 1409 insertions(+), 758 deletions(-) create mode 100644 codex/choices/websocketMessages.json create mode 100644 codex/choices/websocket_messages.py create mode 100644 codex/views/browse_metadata_base.py rename frontend/src/api/{ => v1}/auth.js (100%) rename frontend/src/api/{ => v1}/base.js (100%) rename frontend/src/api/{ => v1}/browser.js (100%) rename frontend/src/api/{ => v1}/metadata.js (63%) rename frontend/src/api/{ => v1}/reader.js (100%) create mode 100644 frontend/src/choices/websocketMessages.json rename frontend/src/{ => components}/comic-name.js (100%) create mode 100644 frontend/src/components/metadata-checkbox.vue create mode 100644 frontend/src/components/metadata-computed-items.js diff --git a/NEWS b/NEWS index f01a98325..240ea4525 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +v0.5.14 +* Metadata view for browse containers. Also observes filters. +* Fix scanning notification +* Fix unable to delete libraries bug +* Covers now regenerate on re-import. + v0.5.13 * Admin Flag for automatically updating codex * Force updates from the admin panel with an Admin Flag action diff --git a/codex/admin.py b/codex/admin.py index 11bd7120a..7df5c497f 100644 --- a/codex/admin.py +++ b/codex/admin.py @@ -176,6 +176,10 @@ def has_change_permission(self, request, obj=None): """Can't Change these.""" return False + def has_delete_permission(self, request, obj=None): + """Sure can delete them tho.""" + return True + def library_link(self, item): """A special feild for linking to the library change page.""" url = resolve_url(admin_urlname(Library._meta, "change"), item.library.id) diff --git a/codex/choices/websocketMessages.json b/codex/choices/websocketMessages.json new file mode 100644 index 000000000..14b1bfdb2 --- /dev/null +++ b/codex/choices/websocketMessages.json @@ -0,0 +1,10 @@ +{ + "user": { + "LIBRARY_CHANGED": "libraryChanged" + }, + "admin": { + "SCAN_LIBRARY": "scanLibrary", + "FAILED_IMPORTS": "failedImports", + "SCAN_DONE": "scanDone" + } +} diff --git a/codex/choices/websocket_messages.py b/codex/choices/websocket_messages.py new file mode 100644 index 000000000..d7a0628ac --- /dev/null +++ b/codex/choices/websocket_messages.py @@ -0,0 +1,10 @@ +"""Static choices that aren't derived from models.""" +from pathlib import Path + +import simplejson as json + + +THIS_DIR = Path(__file__).parent +MESSAGES_FN = f"{THIS_DIR}/websocketMessages.json" +with open(MESSAGES_FN, "r") as messages_file: + MESSAGES = json.load(messages_file) diff --git a/codex/librarian/cover.py b/codex/librarian/cover.py index d0056eec5..fa386db2d 100644 --- a/codex/librarian/cover.py +++ b/codex/librarian/cover.py @@ -4,6 +4,7 @@ from pathlib import Path from comicbox.comic_archive import ComicArchive +from fnvhash import fnv1a_32 from PIL import Image from codex.librarian.queue import QUEUE @@ -18,8 +19,11 @@ COVER_ROOT = Path(f"{CONFIG_STATIC}/covers") MISSING_COVER_FN = "missing_cover.png" +BUILDING_COVER_FN = "building_cover.png" MISSING_COVER_SRC = STATIC_ROOT / "img" / MISSING_COVER_FN MISSING_COVER_FS_PATH = COVER_ROOT / MISSING_COVER_FN +HEX_FILL = 8 +PATH_STEP = 2 LOG = logging.getLogger(__name__) @@ -53,13 +57,30 @@ def purge_all_covers(library): purge_cover(comic) +def hex_path(comic_path): + """Translate an integer into an efficient filesystem path.""" + fnv = fnv1a_32(bytes(str(comic_path), "utf-8")) + hex_str = "{0:0{1}x}".format(fnv, HEX_FILL) + parts = [] + for i in range(0, len(hex_str), PATH_STEP): + parts.append(hex_str[i : i + PATH_STEP]) + path = Path("/".join(parts)) + return path + + +def get_cover_path(comic_path): + """Get path to a cover image, creating the image if not found.""" + cover_path = hex_path(comic_path) + return cover_path.with_suffix(".jpg") + + def create_comic_cover(comic_path, db_cover_path, force=False): """Create a comic cover thumnail and save it to disk.""" - comic = None try: - if not force and db_cover_path == MISSING_COVER_FN: - LOG.debug(f"Cover for {comic_path} missing") + if db_cover_path == MISSING_COVER_FN and not force: + LOG.debug(f"Cover for {comic_path} missing.") return + fs_cover_path = COVER_ROOT / db_cover_path if fs_cover_path.exists() and not force: LOG.debug(f"Cover already exists {comic_path} {db_cover_path}") @@ -67,6 +88,7 @@ def create_comic_cover(comic_path, db_cover_path, force=False): fs_cover_path.parent.mkdir(exist_ok=True, parents=True) if comic_path is None: + print(f"{db_cover_path=}") comic = Comic.objects.only("path").get(cover_path=db_cover_path) comic_path = comic.path @@ -80,7 +102,5 @@ def create_comic_cover(comic_path, db_cover_path, force=False): except Exception as exc: LOG.error(f"Failed to create cover thumb for {comic_path}") LOG.exception(exc) - Comic.objects.filter(cover_path=db_cover_path).update( - cover_path=MISSING_COVER_FN - ) + Comic.objects.filter(comic_path=comic_path).update(cover_path=MISSING_COVER_FN) LOG.warn(f"Marked cover for {comic_path} missing.") diff --git a/codex/librarian/importer.py b/codex/librarian/importer.py index b6dfcc0a8..c2080459b 100644 --- a/codex/librarian/importer.py +++ b/codex/librarian/importer.py @@ -14,8 +14,8 @@ from comicbox.comic_archive import ComicArchive from django.db.models import ForeignKey from django.db.models import ManyToManyField -from fnvhash import fnv1a_32 +from codex.librarian.cover import get_cover_path from codex.librarian.cover import purge_cover from codex.librarian.queue import QUEUE from codex.librarian.queue import ComicCoverCreateTask @@ -105,10 +105,6 @@ class Importer: EXCLUDED_MODEL_KEYS = ("id", "parent_folder") FIELD_PREFIX_LEN = len("codex.Comic.") - # Covers - HEX_FILL = 8 - PATH_STEP = 2 - def __init__(self, library_id, path): """Set the state for this import.""" self.library_id = library_id @@ -116,24 +112,6 @@ def __init__(self, library_id, path): self.car = ComicArchive(path) self.md = self.car.get_metadata() - def hex_path(self): - """Translate an integer into an efficient filesystem path.""" - fnv = fnv1a_32(bytes(str(self.path), "utf-8")) - hex_str = "{0:0{1}x}".format(fnv, self.HEX_FILL) - parts = [] - for i in range(0, len(hex_str), self.PATH_STEP): - parts.append(hex_str[i : i + self.PATH_STEP]) - path = Path("/".join(parts)) - return path - - def get_cover_path(self): - """Get path to a cover image, creating the image if not found.""" - hex_path = self.hex_path() - db_cover_path = hex_path.with_suffix(".jpg") - task = ComicCoverCreateTask(self.path, db_cover_path) - QUEUE.put(task) - return db_cover_path - @staticmethod def get_or_create_simple_model(name, cls): """Update or create a SimpleModel that just has a name.""" @@ -335,9 +313,8 @@ def import_metadata(self): self.md["path"] = self.path self.md["size"] = Path(self.path).stat().st_size self.md["max_page"] = max(self.md["page_count"] - 1, 0) - cover_path = self.get_cover_path() - if cover_path: - self.md["cover_path"] = cover_path + cover_path = get_cover_path(self.path) + self.md["cover_path"] = cover_path if credits: m2m_fields["credits"] = credits @@ -351,6 +328,7 @@ def import_metadata(self): for attr, instance_list in m2m_fields.items(): getattr(comic, attr).set(instance_list) comic.save() + QUEUE.put(ComicCoverCreateTask(self.path, cover_path, True)) # If it works, clear the failed import FailedImport.objects.filter(path=self.path).delete() diff --git a/codex/librarian/librariand.py b/codex/librarian/librariand.py index 0d0842a56..813183ac7 100644 --- a/codex/librarian/librariand.py +++ b/codex/librarian/librariand.py @@ -21,6 +21,7 @@ from multiprocessing import Value +from codex.choices.websocket_messages import MESSAGES from codex.librarian.cover import create_comic_cover from codex.librarian.crond import Crond from codex.librarian.importer import import_comic @@ -47,12 +48,7 @@ from codex.models import Folder from codex.websocket_server import BROADCAST_MSG from codex.websocket_server import BROADCAST_SECRET -from codex.websocket_server import FAILED_IMPORTS_MSG from codex.websocket_server import IPC_SUFFIX -from codex.websocket_server import LIBRARY_CHANGED_MSG -from codex.websocket_server import SCAN_DONE_MSG -from codex.websocket_server import SCAN_ROOT_MSG -from codex.websocket_server import SHUTDOWN_MSG from codex.websocket_server import WS_API_PATH @@ -63,6 +59,7 @@ PORT = Value("i", 9810) # Shared memory overwritten in run.py BROADCAST_URL_TMPL = "ws://localhost:{port}/" + WS_API_PATH + IPC_SUFFIX MAX_WS_ATTEMPTS = 4 +SHUTDOWN_TASK = "shutdown" librarian_proc = None if platform.system() == "Darwin": # XXX Fixes QUEUE sharing with default spawn start method. The spawn @@ -126,22 +123,21 @@ def librarian(main_pid): task = QUEUE.get() try: if isinstance(task, ScanRootTask): - ws = send_json(ws, BROADCAST_MSG, SCAN_ROOT_MSG) + msg = MESSAGES["admin"]["SCAN_LIBRARY"] + ws = send_json(ws, BROADCAST_MSG, msg) scan_root(task.library_id, task.force) elif isinstance(task, ScanDoneTask): if task.failed_imports: - msg = FAILED_IMPORTS_MSG + msg = MESSAGES["admin"]["FAILED_IMPORTS"] else: - msg = SCAN_DONE_MSG + msg = MESSAGES["admin"]["SCAN_DONE"] ws = send_json(ws, BROADCAST_MSG, msg) elif isinstance(task, ComicModifiedTask): import_comic(task.library_id, task.src_path) elif isinstance(task, ComicCoverCreateTask): # Cover creation is cpu bound, farm it out. - pool.apply_async( - create_comic_cover, - args=(task.src_path, task.db_cover_path), - ) + args = (task.src_path, task.db_cover_path, task.force) + pool.apply_async(create_comic_cover, args=args) elif isinstance(task, FolderMovedTask): obj_moved(task.src_path, task.dest_path, Folder) elif isinstance(task, ComicMovedTask): @@ -151,7 +147,8 @@ def librarian(main_pid): elif isinstance(task, FolderDeletedTask): obj_deleted(task.src_path, Folder) elif isinstance(task, LibraryChangedTask): - ws = send_json(ws, BROADCAST_MSG, LIBRARY_CHANGED_MSG) + msg = MESSAGES["user"]["LIBRARY_CHANGED"] + ws = send_json(ws, BROADCAST_MSG, msg) elif isinstance(task, WatcherCronTask): sleep(task.sleep) watcher.set_all_library_watches() @@ -161,7 +158,7 @@ def librarian(main_pid): elif isinstance(task, UpdateCronTask): sleep(task.sleep) update_codex(main_pid, task.force) - elif task == SHUTDOWN_MSG: + elif task == SHUTDOWN_TASK: run = False else: LOG.warning(f"Unhandled task popped: {task}") @@ -195,6 +192,6 @@ def start_librarian(): def stop_librarian(*args, **kwargs): """Stop the librarian process.""" global librarian_proc - QUEUE.put(SHUTDOWN_MSG) + QUEUE.put(SHUTDOWN_TASK) if librarian_proc: librarian_proc.join() diff --git a/codex/librarian/queue.py b/codex/librarian/queue.py index 122f680a6..3982a72d9 100644 --- a/codex/librarian/queue.py +++ b/codex/librarian/queue.py @@ -30,6 +30,7 @@ class ComicCoverCreateTask(ComicTask): """Create a comic cover.""" db_cover_path: str + force: bool @dataclass diff --git a/codex/serializers/browse.py b/codex/serializers/browse.py index 7f0a54212..491a1c550 100644 --- a/codex/serializers/browse.py +++ b/codex/serializers/browse.py @@ -87,9 +87,11 @@ class BrowseObjectSerializer(Serializer): def get_x_cover_path(self, obj): """Ensure comic cover exists for any cover_path we send.""" - task = ComicCoverCreateTask(obj.get("x_path"), obj.get("x_cover_path")) + comic_path = obj.get("x_path") + cover_path = obj.get("x_cover_path") + task = ComicCoverCreateTask(comic_path, cover_path, False) QUEUE.put(task) - return obj.get("x_cover_path") + return cover_path pk = IntegerField(read_only=True) group = CharField(read_only=True, max_length=1) diff --git a/codex/serializers/metadata.py b/codex/serializers/metadata.py index f3f7fbe9e..8f80cc5a8 100644 --- a/codex/serializers/metadata.py +++ b/codex/serializers/metadata.py @@ -1,145 +1,102 @@ """Codex Serializers for the metadata box.""" -import pycountry - from rest_framework.serializers import BooleanField from rest_framework.serializers import CharField from rest_framework.serializers import DecimalField from rest_framework.serializers import IntegerField +from rest_framework.serializers import ListField from rest_framework.serializers import ModelSerializer from rest_framework.serializers import Serializer -from rest_framework.serializers import SerializerMethodField +from rest_framework.serializers import URLField -from codex.models import Comic from codex.models import Credit from codex.models import UserBookmark - - -class NamedModelSerializer(Serializer): - """One serializer for all NamedModels.""" - - pk = IntegerField() - name = CharField(max_length=32) - - -# Cannot use ModelSerializer with Abstract Models... for now. -# class Meta: -# """Model spec.""" -# -# model = NamedModel -# fields = ("pk", "name") -# read_only_fields = fields +from codex.serializers.vuetify import VueCountryChoiceSerializer +from codex.serializers.vuetify import VueIntChoiceSerializer +from codex.serializers.vuetify import VueLanguageChoiceSerializer class CreditSerializer(ModelSerializer): """Credit model serializer.""" - person = NamedModelSerializer(read_only=True) - role = NamedModelSerializer(read_only=True) + person = VueIntChoiceSerializer(read_only=True) + role = VueIntChoiceSerializer(read_only=True) class Meta: """Model spec.""" model = Credit - fields = ("person", "role") + fields = ("pk", "person", "role") read_only_fields = fields -class ComicSerializer(ModelSerializer): +class MetadataSerializer(Serializer): """Serialize the comic model for browser metadata box.""" - # Publish annotations - publisher_name = CharField() - imprint_name = CharField() - series_name = CharField() - volume_name = CharField() - volume_count = IntegerField() - issue_count = IntegerField() + # All the comic pks for a filtered aggregate group + pks = ListField(child=IntegerField()) + + # Aggregate Annotations + size = IntegerField() + coverPath = CharField() # noqa: N815 # UserBookmark annotations + # fit_to = CharField() + # two_pages = BooleanField() bookmark = IntegerField() finished = BooleanField() - fit_to = CharField() - two_pages = BooleanField() + pageCount = IntegerField() # noqa: N815 progress = DecimalField(max_digits=5, decimal_places=2) - # Pycountry - country = SerializerMethodField() - language = SerializerMethodField() - - # Many to many NamedModel - genres = NamedModelSerializer(many=True) - tags = NamedModelSerializer(many=True) - teams = NamedModelSerializer(many=True) - characters = NamedModelSerializer(many=True) - locations = NamedModelSerializer(many=True) - series_groups = NamedModelSerializer(many=True) - story_arcs = NamedModelSerializer(many=True) - credits = CreditSerializer(many=True) - - def get_country(self, obj): - """Long name from alpha2 country.""" - if obj.country: - country = pycountry.countries.lookup(obj.country) - if country: - return country.name - - def get_language(self, obj): - """Long name from alpha2 language.""" - if obj.language: - language = pycountry.languages.lookup(obj.language) - if language: - return language.name - - class Meta: - """Fields to serialize.""" - - model = Comic - fields = ( - "pk", - "publisher_name", - "imprint_name", - "series_name", - "volume_name", - "volume_count", - "issue", - "issue_count", - "title", - "cover_path", - "year", - "month", - "day", - "format", - "read_ltr", - "size", - "web", - "user_rating", - "critical_rating", - "maturity_rating", - "summary", - "description", - "notes", - # Pycountry alpha2 - "country", - "language", - # Many to many NamedModels - "genres", - "tags", - "teams", - "characters", - "locations", - "series_groups", - "story_arcs", - "scan_info", - "credits", - # UserBookmark annotations - "finished", - "fit_to", - "two_pages", - "bookmark", - "page_count", - "progress", - ) - read_only_fields = fields + # Publish annotations + publisherChoices = VueIntChoiceSerializer(many=True, allow_null=True) # noqa: N815 + imprintChoices = VueIntChoiceSerializer(many=True, allow_null=True) # noqa: N815 + seriesChoices = VueIntChoiceSerializer(many=True, allow_null=True) # noqa: N815 + volumeChoices = VueIntChoiceSerializer(many=True, allow_null=True) # noqa: N815 + volumeCountChoices = VueIntChoiceSerializer( # noqa: N815 + many=True, allow_null=True + ) + issueCountChoices = VueIntChoiceSerializer(many=True, allow_null=True) # noqa: N815 + + # Value Choices + issueChoices = ListField( # noqa: N815 + child=DecimalField(max_digits=5, decimal_places=1), allow_null=True + ) + titleChoices = ListField(child=CharField(), allow_null=True) # noqa: N815 + yearChoices = ListField(child=IntegerField(), allow_null=True) # noqa: N815 + monthChoices = ListField(child=IntegerField(), allow_null=True) # noqa: N815 + dayChoices = ListField(child=IntegerField(), allow_null=True) # noqa: N815 + formatChoices = ListField(child=CharField(), allow_null=True) # noqa: N815 + readLTRChoices = ListField(child=BooleanField(), allow_null=True) # noqa: N815 + webChoices = ListField(child=URLField(), allow_null=True) # noqa: N815 + userRatingChoices = ListField(child=CharField(), allow_null=True) # noqa: N815 + criticalRatingChoices = ListField(child=CharField(), allow_null=True) # noqa: N815 + maturityRatingChoices = ListField(child=CharField(), allow_null=True) # noqa: N815 + scanInfoChoices = ListField(child=CharField(), allow_null=True) # noqa: N815 + # Too big for choices and doesn't really make sense anyway + # summaryChoices = ListField(child=CharField(), allow_null=True) # noqa: N815 + # descriptionChoices = ListField(child=CharField(), allow_null=True) # noqa: N815 + # notesChoices = ListField(child=CharField(), allow_null=True) # noqa: N815 + summary = CharField(allow_null=True) + description = CharField(allow_null=True) + notes = CharField(allow_null=True) + countryChoices = VueCountryChoiceSerializer( # noqa: N815 + many=True, allow_null=True + ) + languageChoices = VueLanguageChoiceSerializer( # noqa: N815 + many=True, allow_null=True + ) + + # Many to Many Choices + genresChoices = VueIntChoiceSerializer(many=True, allow_null=True) # noqa: N815 + tagsChoices = VueIntChoiceSerializer(many=True, allow_null=True) # noqa: N815 + teamsChoices = VueIntChoiceSerializer(many=True, allow_null=True) # noqa: N815 + charactersChoices = VueIntChoiceSerializer(many=True, allow_null=True) # noqa: N815 + locationsChoices = VueIntChoiceSerializer(many=True, allow_null=True) # noqa: N815 + seriesGroupsChoices = VueIntChoiceSerializer( # noqa: N815 + many=True, allow_null=True + ) + storyArcsChoices = VueIntChoiceSerializer(many=True, allow_null=True) # noqa: N815 + creditsChoices = CreditSerializer(many=True, allow_null=True) # noqa: N815 class UserBookmarkFinishedSerializer(ModelSerializer): diff --git a/codex/serializers/vuetify.py b/codex/serializers/vuetify.py index 9c6b56e09..e3c22adbf 100644 --- a/codex/serializers/vuetify.py +++ b/codex/serializers/vuetify.py @@ -1,7 +1,17 @@ """Vuetify Choice Serializers.""" +import pycountry + +from rest_framework.serializers import BooleanField from rest_framework.serializers import CharField +from rest_framework.serializers import DecimalField from rest_framework.serializers import IntegerField from rest_framework.serializers import Serializer +from rest_framework.serializers import SerializerMethodField +from rest_framework.serializers import URLField + + +# TODO after edit works. Some of these may never be used. +# Boolean, Char, Decimal, URL class VueChoiceSerializer(Serializer): @@ -15,7 +25,7 @@ class Meta: abstract = True -class VueStringChoiceSerializer(VueChoiceSerializer): +class VueCharChoiceSerializer(VueChoiceSerializer): """Vuetify string choice format.""" value = CharField(read_only=True) @@ -25,3 +35,69 @@ class VueIntChoiceSerializer(VueChoiceSerializer): """Vuetify int choice format.""" value = IntegerField(read_only=True) + + +class VueDecimalChoiceSerializer(VueChoiceSerializer): + """Vuetify decimal choice format.""" + + value = DecimalField(max_digits=5, decimal_places=2, read_only=True) + + +class VueBooleanChoiceSerializer(VueChoiceSerializer): + """Vuetify bool choice format.""" + + value = BooleanField(read_only=True) + + +class VueURLChoiceSerializer(VueChoiceSerializer): + """Vuetify URL choice format.""" + + value = URLField(read_only=True) + + +class VueMethodChoiceSerializer(Serializer): + """Create the text in the choice with a Method.""" + + value = SerializerMethodField() + text = SerializerMethodField() + + class Meta: + """Abstract Class.""" + + abstract = True + + +class VuePyCountryChoiceSerializer(VueMethodChoiceSerializer): + """Abstract class for looking up pycounty texts from value.""" + + class Meta: + """Abstract Class.""" + + abstract = True + + def get_value(self, value): + return value + + def get_text(self, value): + """Long name from alpha2 pycountry module.""" + if not value: + return None + if len(value) == 2: + # fix for https://github.com/flyingcircusio/pycountry/issues/41 + lookup_obj = self.LOOKUP_MODULE.get(alpha_2=value) + else: + lookup_obj = self.LOOKUP_MODULE.lookup(value) + if lookup_obj: + return lookup_obj.name + + +class VueCountryChoiceSerializer(VuePyCountryChoiceSerializer): + """For pycountries.""" + + LOOKUP_MODULE = pycountry.countries + + +class VueLanguageChoiceSerializer(VuePyCountryChoiceSerializer): + """For pycountry languages.""" + + LOOKUP_MODULE = pycountry.languages diff --git a/codex/settings.py b/codex/settings.py index b0d1a14fb..f58d77b59 100644 --- a/codex/settings.py +++ b/codex/settings.py @@ -151,7 +151,7 @@ "ENGINE": "django.db.backends.sqlite3", "NAME": CONFIG_PATH / "db.sqlite3", "CONN_MAX_AGE": 600, - "OPTIONS": {"timeout": 20}, + "OPTIONS": {"timeout": 120}, }, } SESSION_ENGINE = "django.contrib.sessions.backends.cached_db" diff --git a/codex/urls_api_v1.py b/codex/urls_api_v1.py index b33fbe8ee..74958d401 100644 --- a/codex/urls_api_v1.py +++ b/codex/urls_api_v1.py @@ -22,7 +22,7 @@ from codex.views.browse_choices import BrowseChoiceView from codex.views.browser import BrowseView from codex.views.metadata import ComicDownloadView -from codex.views.metadata import ComicMetadataView +from codex.views.metadata import MetadataView from codex.views.metadata import UserBookmarkFinishedView from codex.views.reader import ComicBookmarkView from codex.views.reader import ComicOpenedView @@ -31,9 +31,6 @@ from codex.views.scan_notify import ScanNotifyView -# from django.urls import include - - app_name = "api" urlpatterns = [ # @@ -49,11 +46,10 @@ name="browse_choices", ), path( - "browse///mark_read", + "browse///mark_read", UserBookmarkFinishedView.as_view(), name="mark_read", ), - path("browse/scan_notify", ScanNotifyView.as_view(), name="scan_notify"), path( "comic//archive.cbz", ComicDownloadView.as_view(), @@ -77,12 +73,16 @@ ComicSettingsView.as_view(), name="comic_settings", ), + # + # Metadata path( - "comic/settings", - ComicSettingsView.as_view(), - name="comic_settings", + "metadata//", + MetadataView.as_view(), + name="metadata", ), - path("comic//metadata", ComicMetadataView.as_view(), name="comic_metadata"), + # + # Notify + path("browse/scan_notify", ScanNotifyView.as_view(), name="scan_notify"), # # Auth path("auth/register", RegisterView.as_view(), name="register"), diff --git a/codex/views/browse_base.py b/codex/views/browse_base.py index 2ecb33e7f..c104b9007 100644 --- a/codex/views/browse_base.py +++ b/codex/views/browse_base.py @@ -100,6 +100,13 @@ def get_browse_container_filter(self): return container_filter + def get_aggregate_filter(self): + """Return the filter for making aggregates.""" + bookmark_filter_join = self.get_bookmark_filter() + comic_attribute_filter = self.get_comic_attribute_filter() + aggregate_filter = bookmark_filter_join & comic_attribute_filter + return aggregate_filter + def get_query_filters(self, choices=False): """Return the main object filter and the one for aggregates.""" # XXX This logic is complicated and confusing @@ -116,9 +123,7 @@ def get_query_filters(self, choices=False): if choices: aggregate_filter = None else: - bookmark_filter_join = self.get_bookmark_filter() - comic_attribute_filter = self.get_comic_attribute_filter() - aggregate_filter = bookmark_filter_join & comic_attribute_filter + aggregate_filter = self.get_aggregate_filter() object_filter &= aggregate_filter return object_filter, aggregate_filter diff --git a/codex/views/browse_metadata_base.py b/codex/views/browse_metadata_base.py new file mode 100644 index 000000000..cd9aad8e7 --- /dev/null +++ b/codex/views/browse_metadata_base.py @@ -0,0 +1,167 @@ +"""Base view for metadata annotations.""" +from decimal import Decimal + +from bidict import bidict +from django.db.models import Avg +from django.db.models import BooleanField +from django.db.models import Count +from django.db.models import DecimalField +from django.db.models import F +from django.db.models import Min +from django.db.models import OuterRef +from django.db.models import Q +from django.db.models import Subquery +from django.db.models import Sum +from django.db.models import Value +from django.db.models.functions import Cast +from django.db.models.functions import Coalesce +from django.db.models.functions import NullIf + +from codex.models import Comic +from codex.models import Folder +from codex.models import Imprint +from codex.models import Publisher +from codex.models import Series +from codex.models import Volume +from codex.views.browse_base import BrowseBaseView + + +class BrowseMetadataBase(BrowseBaseView): + """Base class for views that need special metadata annotations.""" + + COMIC_GROUP = "c" + GROUP_MODEL = bidict( + { + "r": None, + "p": Publisher, + "i": Imprint, + "s": Series, + "v": Volume, + COMIC_GROUP: Comic, + BrowseBaseView.FOLDER_GROUP: Folder, + } + ) + SORT_AGGREGATE_FUNCS = { + "created_at": Min, + "critical_rating": Avg, + "date": Min, + "page_count": Sum, + "size": Sum, + "user_rating": Avg, + } + DEFAULT_ORDER_KEY = "sort_name" + + def get_aggregate_func(self, attr, model, aggregate_filter): + """Get a complete function for aggregating an attribute.""" + agg_func = self.SORT_AGGREGATE_FUNCS.get(attr) + if model == Comic or agg_func is None: + order_func = F(attr) + else: + order_func = agg_func(f"comic__{attr}", filter=aggregate_filter) + return order_func + + def get_order_by(self, order_key, model, use_order_value): + """ + Create the order_by list. + + Order on pk to give duplicates a consistant position. + """ + sort_reverse = self.params.get("sort_reverse") + if sort_reverse: + order_prefix = "-" + else: + order_prefix = "" + if use_order_value: + order_key = "order_value" + order_by = [order_prefix + order_key, order_prefix + "pk"] + if model in (Comic, Folder): + # This keeps position stability for duplicate comics & folders + order_by += ["library"] + return order_by + + def annotate_cover_path(self, queryset, model, aggregate_filter, order_key): + """Annotate the query set for the coverpath for the sort.""" + # Select comics for the children by an outer ref for annotation + # Order the decendent comics by the sort argumentst + if model == Comic: + cover_path_subquery = F("cover_path") + else: + # Cover Path from sorted children. + # XXX Don't know how to make this a join + # because it selects by order_by but wants the cover_path + model_ref = model.__name__.lower() + model_container_filter = Q(**{model_ref: OuterRef("pk")}) + comics = Comic.objects.filter(model_container_filter & aggregate_filter) + order_by = self.get_order_by(order_key, Comic, False) + comics = comics.order_by(*order_by) + cover_comic_path = comics.values("cover_path") + cover_path_subquery = Subquery(cover_comic_path[:1]) + obj_list = queryset.annotate(x_cover_path=cover_path_subquery) + return obj_list + + def annotate_children_and_page_count(self, obj_list, aggregate_filter): + child_count_sum = Count("comic__pk", distinct=True, filter=aggregate_filter) + # Hoist up total page_count of children + # Used for sorting and progress + page_count_sum = Sum("comic__page_count", filter=aggregate_filter) + + obj_list = obj_list.annotate( + child_count=child_count_sum, x_page_count=page_count_sum + ) + return obj_list + + def get_userbookmark_filter(self, for_comic=False): + """Get a filter for my session or user defined bookmarks.""" + rel_to_ub = "userbookmark" + if not for_comic: + rel_to_ub = "comic__userbookmark" + + if self.request.user.is_authenticated: + my_bookmarks_kwargs = {f"{rel_to_ub}__user": self.request.user} + else: + my_bookmarks_kwargs = { + f"{rel_to_ub}__session__session_key": self.request.session.session_key + } + return Q(**my_bookmarks_kwargs) + + def annotate_bookmarks(self, obj_list): + """Hoist up bookmark annoations.""" + ub_filter = self.get_userbookmark_filter() + + # Hoist up: are the children finished or unfinished? + finished_aggregate = Cast( + NullIf( + Coalesce( + Avg( # distinct average of user's finished values + "comic__userbookmark__finished", + filter=ub_filter, + distinct=True, + output_field=DecimalField(), + ), + False, # Null db values counted as False + ), + Value(0.5), # Null result if mixed true & false + ), + BooleanField(), # Finally ends up as a ternary boolean + ) + + # Hoist up the bookmark + bookmark_sum = Sum("comic__userbookmark__bookmark", filter=ub_filter) + + obj_list = obj_list.annotate(finished=finished_aggregate, bookmark=bookmark_sum) + + return obj_list + + @staticmethod + def annotate_progress(queryset): + """Compute progress for each member of a queryset.""" + # Requires bookmark and annotation hoisted from userbookmarks. + # Requires x_page_count native to comic or aggregated + queryset = queryset.annotate( + progress=Coalesce( + F("bookmark") * Decimal("1.0") / F("x_page_count") * 100, + Value(0.00), + output_field=DecimalField(), + ) + ) + return queryset diff --git a/codex/views/browser.py b/codex/views/browser.py index 53cdf6f76..cd9f14906 100644 --- a/codex/views/browser.py +++ b/codex/views/browser.py @@ -1,25 +1,12 @@ """Views for browsing comic library.""" import logging -from bidict import bidict from django.core.paginator import EmptyPage from django.core.paginator import Paginator -from django.db.models import Avg -from django.db.models import BooleanField from django.db.models import CharField -from django.db.models import Count -from django.db.models import DecimalField from django.db.models import F from django.db.models import IntegerField -from django.db.models import Min -from django.db.models import OuterRef -from django.db.models import Q -from django.db.models import Subquery -from django.db.models import Sum from django.db.models import Value -from django.db.models.functions import Cast -from django.db.models.functions import Coalesce -from django.db.models.functions import NullIf from rest_framework.exceptions import PermissionDenied from rest_framework.exceptions import ValidationError from rest_framework.response import Response @@ -40,31 +27,18 @@ from codex.serializers.browse import BrowserSettingsSerializer from codex.settings import CACHE_PATH from codex.views.auth import IsAuthenticatedOrEnabledNonUsers -from codex.views.browse_base import BrowseBaseView -from codex.views.mixins import UserBookmarkMixin +from codex.views.browse_metadata_base import BrowseMetadataBase PACKAGE_NAME = "codex" LOG = logging.getLogger(__name__) -class BrowseView(BrowseBaseView, UserBookmarkMixin): +class BrowseView(BrowseMetadataBase): """Browse comics with a variety of filters and sorts.""" permission_classes = [IsAuthenticatedOrEnabledNonUsers] - COMIC_GROUP = "c" - GROUP_MODEL = bidict( - { - "r": None, - "p": Publisher, - "i": Imprint, - "s": Series, - "v": Volume, - COMIC_GROUP: Comic, - BrowseBaseView.FOLDER_GROUP: Folder, - } - ) GROUP_SHOW_FLAGS = { # Show flags to root group equivalients "r": "p", @@ -73,15 +47,6 @@ class BrowseView(BrowseBaseView, UserBookmarkMixin): "s": "v", "v": "c", } - SORT_AGGREGATE_FUNCS = { - "created_at": Min, - "critical_rating": Avg, - "date": Min, - "page_count": Sum, - "size": Sum, - "user_rating": Avg, - } - DEFAULT_ORDER_KEY = "sort_name" CHOICES_RELATIONS = ("decade", "characters") MAX_OBJ_PER_PAGE = 100 ORPHANS = MAX_OBJ_PER_PAGE / 20 @@ -158,25 +123,6 @@ def get_model_group(self): return self.COMIC_GROUP - def get_order_by(self, order_key, model, use_order_value): - """ - Create the order_by list. - - Order on pk to give duplicates a consistant position. - """ - sort_reverse = self.params.get("sort_reverse") - if sort_reverse: - order_prefix = "-" - else: - order_prefix = "" - if use_order_value: - order_key = "order_value" - order_by = [order_prefix + order_key, order_prefix + "pk"] - if model in (Comic, Folder): - # This keeps position stability for duplicate comics & folders - order_by += ["library"] - return order_by - def add_annotations(self, obj_list, model, aggregate_filter): """ Annotations for display and sorting. @@ -187,20 +133,9 @@ def add_annotations(self, obj_list, model, aggregate_filter): ########################################## # Annotate children count and page count # ########################################## - if model == Comic: - child_count_sum = Value(1, IntegerField()) - page_count_sum = F("page_count") - else: - child_count_sum = Count("comic__pk", distinct=True, filter=aggregate_filter) - # Hoist up total page_count of children - # Used for sorting and progress - page_count_sum = Sum("comic__page_count", filter=aggregate_filter) - + obj_list = self.annotate_children_and_page_count(obj_list, aggregate_filter) # EXTRA FILTER for empty containers - obj_list = obj_list.annotate(child_count=child_count_sum).filter( - child_count__gt=0 - ) - obj_list = obj_list.annotate(x_page_count=page_count_sum) + obj_list = obj_list.filter(child_count__gt=0) ################## # Annotate Group # @@ -213,29 +148,7 @@ def add_annotations(self, obj_list, model, aggregate_filter): ################################ # Annotate userbookmark hoists # ################################ - ub_filter = self.get_userbookmark_filter() - - # Hoist up: are the children finished or unfinished? - finished_aggregate = Cast( - NullIf( - Coalesce( - Avg( # distinct average of user's finished values - "comic__userbookmark__finished", - filter=ub_filter, - distinct=True, - output_field=DecimalField(), - ), - False, # Null db values counted as False - ), - Value(0.5), # Null result if mixed true & false - ), - BooleanField(), # Finally ends up as a ternary boolean - ) - - # Hoist up the bookmark - bookmark_sum = Sum("comic__userbookmark__bookmark", filter=ub_filter) - - obj_list = obj_list.annotate(finished=finished_aggregate, bookmark=bookmark_sum) + obj_list = self.annotate_bookmarks(obj_list) ##################### # Annotate progress # @@ -253,32 +166,15 @@ def add_annotations(self, obj_list, model, aggregate_filter): # Sortable aggregates # ####################### order_key = self.params.get("sort_by", self.DEFAULT_ORDER_KEY) - agg_func = self.SORT_AGGREGATE_FUNCS.get(order_key) - if model == Comic or agg_func is None: - order_func = F(order_key) - else: - order_func = agg_func(f"comic__{order_key}", filter=aggregate_filter) + order_func = self.get_aggregate_func(order_key, model, aggregate_filter) obj_list = obj_list.annotate(order_value=order_func) ####################### # Annotate Cover Path # ####################### - # Select comics for the children by an outer ref for annotation - # Order the decendent comics by the sort argumentst - if model == Comic: - cover_path_subquery = F("cover_path") - else: - # Cover Path from sorted children. - # XXX Don't know how to make this a join - # because it selects by order_by but wants the cover_path - model_ref = model.__name__.lower() - model_container_filter = Q(**{model_ref: OuterRef("pk")}) - comics = Comic.objects.filter(model_container_filter & aggregate_filter) - order_by = self.get_order_by(order_key, Comic, False) - comics = comics.order_by(*order_by) - cover_comic_path = comics.values("cover_path") - cover_path_subquery = Subquery(cover_comic_path[:1]) - obj_list = obj_list.annotate(x_cover_path=cover_path_subquery) + obj_list = self.annotate_cover_path( + obj_list, model, aggregate_filter, order_key + ) ####################### # Annotate name fields # diff --git a/codex/views/metadata.py b/codex/views/metadata.py index 06f16b00f..5d92a5fa7 100644 --- a/codex/views/metadata.py +++ b/codex/views/metadata.py @@ -1,21 +1,19 @@ """View for marking comics read and unread.""" import logging +import time -from django.db.models import BooleanField -from django.db.models import CharField -from django.db.models import F -from django.db.models import IntegerField -from django.db.models import Value +from django.db.models import FilteredRelation from django.http import FileResponse from django.http import Http404 from rest_framework.response import Response from rest_framework.views import APIView from codex.models import Comic -from codex.serializers.metadata import ComicSerializer +from codex.serializers.metadata import MetadataSerializer from codex.serializers.metadata import UserBookmarkFinishedSerializer +from codex.settings import DEBUG from codex.views.auth import IsAuthenticatedOrEnabledNonUsers -from codex.views.browser import BrowseView +from codex.views.browse_metadata_base import BrowseMetadataBase from codex.views.mixins import SessionMixin from codex.views.mixins import UserBookmarkMixin @@ -43,6 +41,8 @@ def get(self, request, *args, **kwargs): class UserBookmarkFinishedView(APIView, SessionMixin, UserBookmarkMixin): """Mark read or unread recursively.""" + # TODO possibly combine with ComicBookmarkView + permission_classes = [IsAuthenticatedOrEnabledNonUsers] def patch(self, request, *args, **kwargs): @@ -50,8 +50,8 @@ def patch(self, request, *args, **kwargs): serializer = UserBookmarkFinishedSerializer(data=request.data) serializer.is_valid(raise_exception=True) - browse_type = self.kwargs.get("browse_type") - relation = BrowseView.GROUP_RELATION.get(browse_type) + group = self.kwargs.get("group") + relation = BrowseMetadataBase.GROUP_RELATION.get(group) pk = self.kwargs.get("pk") # Optimizing this call with only seems to fail the subsequent updates comics = Comic.objects.filter(**{relation: pk}) @@ -65,52 +65,275 @@ def patch(self, request, *args, **kwargs): return Response() -class ComicMetadataView(APIView, SessionMixin, UserBookmarkMixin): +class MetadataView(BrowseMetadataBase, SessionMixin, UserBookmarkMixin): """Comic metadata.""" permission_classes = [IsAuthenticatedOrEnabledNonUsers] - queryset = Comic.objects.all() + + CONTAINER_AGG_SERIALIZER_MAP = { + "bookmark": "bookmark", + "child_count": "childCount", + "x_cover_path": "coverPath", + "finished": "finished", + "progress": "progress", + "size": "size", + "x_page_count": "pageCount", + } + CONTAINER_VALUES = tuple( + list(CONTAINER_AGG_SERIALIZER_MAP.keys()) + ["x_comic__pk"] + ) + COMIC_FK_SERIALIZER_MAP = { + "imprint": "imprintChoices", + "publisher": "publisherChoices", + "series": "seriesChoices", + "volume": "volumeChoices", + } + COMIC_M2M_SERIALIZER_MAP = { + "characters": "charactersChoices", + "genres": "genresChoices", + "locations": "locationsChoices", + "series_groups": "seriesGroupsChoices", + "story_arcs": "storyArcsChoices", + "tags": "tagsChoices", + "teams": "teamsChoices", + } + # TODO do vue choice transforms on the client side + VUE_CHOICE_KEYS = tuple( + list(COMIC_FK_SERIALIZER_MAP.values()) + list(COMIC_M2M_SERIALIZER_MAP.values()) + ) + + COMIC_FIELD_SERIALIZER_MAP = { + "country": "countryChoices", + "critical_rating": "criticalRatingChoices", + "day": "dayChoices", + "description": "descriptionChoices", + "format": "formatChoices", + "issue": "issueChoices", + "language": "languageChoices", + "maturity_rating": "maturityRatingChoices", + "month": "monthChoices", + "notes": "notesChoices", + "read_ltr": "readLTRChoices", + "scan_info": "scanInfoChoices", + "summary": "summaryChoices", + "title": "titleChoices", + "user_rating": "userRatingChoices", + "web": "webChoices", + "year": "yearChoices", + "series.volume_count": "volumeCountChoices", + "volume.issue_count": "issueCountChoices", + } + + TEXT_AREA_KEYS = set(("summary", "description", "notes")) + + def query_container(self): + """Return container aggregate data and comic pks.""" + + # Create the aggregates like we do for the browser + group = self.kwargs["group"] + pk = self.kwargs["pk"] + + model = self.GROUP_MODEL[group] + aggregate_filter = self.get_aggregate_filter() + + obj = model.objects.filter(pk=pk) + if model != Comic: + agg_func = self.get_aggregate_func("size", model, aggregate_filter) + obj = obj.annotate(size=agg_func) + order_key = self.params.get("sort_by", self.DEFAULT_ORDER_KEY) + obj = self.annotate_cover_path(obj, model, aggregate_filter, order_key) + obj = self.annotate_children_and_page_count(obj, aggregate_filter) + obj = self.annotate_bookmarks(obj) + obj = self.annotate_progress(obj) + obj = obj.annotate( + x_comic=FilteredRelation("comic", condition=aggregate_filter) + ) + # Get the values as a dict + container_values = obj.values(*self.CONTAINER_VALUES) + + # Copy the values into a dict with serializer names + comic_summary = {"pks": set()} + for obj in container_values: + comic_summary["pks"].add(obj.get("x_comic__pk")) + first_obj = container_values[0] + for ( + query_key, + serializer_key, + ) in self.CONTAINER_AGG_SERIALIZER_MAP.items(): + comic_summary[serializer_key] = first_obj.get(query_key) + + return comic_summary + + @staticmethod + def ensure_collection(comic_summary, serializer_key, comic_pk, collection_type): + """Ensure a set or dict exists to populate.""" + if serializer_key not in comic_summary: + comic_summary[serializer_key] = dict() + + if comic_pk not in comic_summary[serializer_key]: + comic_summary[serializer_key][comic_pk] = collection_type() + + def query_comics(self, pks): + """ + Aggregate comic data in python because sqllite doesn't have array + fields. + """ + comics = Comic.objects.filter(pk__in=pks).prefetch_related() + comic_summary = {"pks": set()} + for comic in comics: + comic_summary["pks"].add(comic.pk) + # FIELDS + for ( + long_field, + serializer_key, + ) in self.COMIC_FIELD_SERIALIZER_MAP.items(): + # Add the value to a set + self.ensure_collection(comic_summary, serializer_key, comic.pk, set) + fields = long_field.split(".") + relation = comic + for field in fields: + # walk the relation chain + value = getattr(relation, field, None) + relation = value + comic_summary[serializer_key][comic.pk].add(value) + # FKS WITH NAMES + for ( + relation, + serializer_key, + ) in self.COMIC_FK_SERIALIZER_MAP.items(): + self.ensure_collection(comic_summary, serializer_key, comic.pk, dict) + obj = getattr(comic, relation) + value = obj.pk + text = obj.name + comic_summary[serializer_key][comic.pk][value] = text + # MANY TO MANY RELATIONS WITH PKS & NAMES + for ( + relation, + serializer_key, + ) in self.COMIC_M2M_SERIALIZER_MAP.items(): + self.ensure_collection(comic_summary, serializer_key, comic.pk, dict) + m2m = getattr(comic, relation) + for obj in m2m.all(): + value = obj.pk + text = obj.name + comic_summary[serializer_key][comic.pk][value] = text + # CREDITS ARE SPECIAL M2M RELATIONS + for credit in comic.credits.all(): + self.ensure_collection(comic_summary, "credit_summary", comic.pk, dict) + # expand the credit object later if needed. + comic_summary["credit_summary"][comic.pk][credit.pk] = credit + return comic_summary + + @staticmethod + def dict_to_vue_choices(rel_dict): + """transform a pk -> value dict into a vue_choice.""" + choices = [] + if rel_dict: + for value, text in rel_dict.items(): + vue_choice = {"value": value, "text": text} + choices.append(vue_choice) + if len(choices) == 0 or len(choices) == 1 and choices[0]["value"] is None: + choices = None + return choices + + @staticmethod + def credit_vue_choice(obj): + """Create a vue choice from a db object with a pk and name.""" + return {"value": obj.pk, "text": obj.name} + + def pre_serialize(self, comic_summary): + """ + If aggregated sets or dicts for all comics are identical return + only one of them. Otherwise return null. + """ + # TODO: most of this will be rewritten in APIv2 + + # LISTS OF VALUES + for serializer_key in self.COMIC_FIELD_SERIALIZER_MAP.values(): + last_set = None + for value_set in comic_summary[serializer_key].values(): + if last_set is not None and value_set != last_set: + last_set = None + break + last_set = value_set + if last_set == set([None]): + last_set = None + comic_summary[serializer_key] = last_set + + # PK TO NAME DICTS TRANSFORM INTO VUE CHOICES + for serializer_key in self.VUE_CHOICE_KEYS: + last_dict = None + for value_dict in comic_summary[serializer_key].values(): + if last_dict is not None and value_dict.keys() != last_dict.keys(): + last_dict = None + break + last_dict = value_dict + comic_summary[serializer_key] = self.dict_to_vue_choices(last_dict) + + # CREDITS ARE SPECIAL VUE CHOICES + last_credit_dict = None + credit_summary = comic_summary.get("credit_summary") + if credit_summary: + for credit_dict in comic_summary["credit_summary"].values(): + if ( + last_credit_dict is not None + and credit_dict.keys() != last_credit_dict.keys() + ): + last_credit_dict = None + break + last_credit_dict = credit_dict + comic_summary["credit_summary"] = None + + # CREDIT TO VUE CHOICE TRANSFORM + if last_credit_dict: + credit_choices = [] + for pk, credit in last_credit_dict.items(): + value = { + "pk": pk, + "person": self.credit_vue_choice(credit.person), + "role": self.credit_vue_choice(credit.role), + } + credit_choices.append(value) + else: + credit_choices = None + + comic_summary["creditsChoices"] = credit_choices + + # Text Areas can't select choices, and they're big so only pass + # them through if there's one of them. + for key in self.TEXT_AREA_KEYS: + choices_key = f"{key}Choices" + choices = comic_summary.get(choices_key) + if choices and len(choices) == 1: + comic_summary[key] = choices.pop() + else: + comic_summary[key] = None + + return comic_summary + + @staticmethod + def report_time(start_time, num_comics): + """ + Calculate how long it takes per comic to aggregate metadata. + Used in the magic number for the progress circle. + """ + elapsed = time.time() - start_time + cps = num_comics / elapsed + LOG.debug(f"{num_comics} comics / {elapsed:.2g} secs = {cps:.2g} CPS") def get(self, request, *args, **kwargs): """Get metadata for a single comic.""" - pk = kwargs.get("pk") - ub = self.get_user_bookmark(pk) - if ub: - fit_to = ub.fit_to - two_pages = ub.two_pages - finished = ub.finished - bookmark = ub.bookmark - else: - fit_to = None - two_pages = None - finished = None - bookmark = None - - # XXX Django 3.2 will supported nested Filtered Relations - # This filtered relation is simpler than filtering on every relation - # my_bookmark=FilteredRelation("userbookmark", condition=ub_filter), - # fit_to=F("userbookmark__fit_to"), - # two_pages=F("my_bookmark__two_pages"), - # finished=F("my_bookmark__finished"), - # bookmark=F("my_bookmark__bookmark"), - - comic = Comic.objects.annotate( - fit_to=Value(fit_to, CharField()), - two_pages=Value(two_pages, BooleanField()), - finished=Value(finished, BooleanField()), - bookmark=Value(bookmark, IntegerField()), - publisher_name=F("publisher__name"), - imprint_name=F("imprint__name"), - series_name=F("series__name"), - volume_count=F("series__volume_count"), - volume_name=F("volume__name"), - issue_count=F("volume__issue_count"), - x_page_count=F("page_count"), - ) + start_time = time.time() + # Init + self.params = self.get_session(self.BROWSE_KEY) + + container = self.query_container() + comic_data = self.query_comics(container["pks"]) + comic_summary = self.pre_serialize(comic_data) + comic_summary.update(container) - # Annotate progress - comic = self.annotate_progress(comic) + serializer = MetadataSerializer(comic_summary) + if DEBUG: + self.report_time(start_time, len(container["pks"])) - res = comic.select_related().prefetch_related().get(pk=pk) - serializer = ComicSerializer(res) return Response(serializer.data) diff --git a/codex/views/mixins.py b/codex/views/mixins.py index f2f4e5e55..b08df7fd3 100644 --- a/codex/views/mixins.py +++ b/codex/views/mixins.py @@ -1,13 +1,7 @@ """Manage user sessions with appropriate defaults.""" from copy import copy -from decimal import Decimal from django.contrib.sessions.models import Session -from django.db.models import DecimalField -from django.db.models import F -from django.db.models import Q -from django.db.models import Value -from django.db.models.functions import Coalesce from codex.choices.static import DEFAULTS from codex.models import Comic @@ -108,31 +102,3 @@ def update_user_bookmark(self, updates, comic=None, pk=None): defaults = copy(search_kwargs) defaults.update(updates) UserBookmark.objects.update_or_create(defaults=defaults, **search_kwargs) - - def get_userbookmark_filter(self, for_comic=False): - """Get a filter for my session or user defined bookmarks.""" - rel_to_ub = "userbookmark" - if not for_comic: - rel_to_ub = "comic__userbookmark" - - if self.request.user.is_authenticated: - my_bookmarks_kwargs = {f"{rel_to_ub}__user": self.request.user} - else: - my_bookmarks_kwargs = { - f"{rel_to_ub}__session__session_key": self.request.session.session_key - } - return Q(**my_bookmarks_kwargs) - - @staticmethod - def annotate_progress(queryset): - """Compute progress for each member of a queryset.""" - # Requires bookmark and annotation hoisted from userbookmarks. - # Requires x_page_count native to comic or aggregated - queryset = queryset.annotate( - progress=Coalesce( - F("bookmark") * Decimal("1.0") / F("x_page_count") * 100, - Value(0.00), - output_field=DecimalField(), - ) - ) - return queryset diff --git a/codex/websocket_server.py b/codex/websocket_server.py index 9e6ef3b16..2e92eb278 100644 --- a/codex/websocket_server.py +++ b/codex/websocket_server.py @@ -13,6 +13,8 @@ from django.core.cache import cache from simplejson import JSONDecodeError +from codex.choices.websocket_messages import MESSAGES + LOG = getLogger(__name__) @@ -24,13 +26,6 @@ BROADCAST_MSG = "broadcast" # Shared memory broadcast security BROADCAST_SECRET = Value("i", random.randint(0, 100)) -LIBRARY_CHANGED_MSG = "libraryChanged" -SCAN_ROOT_MSG = "scanLibrary" -FAILED_IMPORTS_MSG = "failedImports" -SCAN_DONE_MSG = "scanDone" -ADMIN_MESSAGES = (SCAN_ROOT_MSG, FAILED_IMPORTS_MSG, SCAN_DONE_MSG) -# XXX if messages gets too big export the consts into a json -# for the frontend WS_API_PATH = "api/v1/ws" ADMIN_SUFFIX = "/a" IPC_SUFFIX = "/ipc" @@ -77,7 +72,7 @@ async def websocket_application(scope, receive, send): msg_type == BROADCAST_MSG and msg.get("secret") == BROADCAST_SECRET.value ): - if message in ADMIN_MESSAGES: + if message in MESSAGES["admin"]: # don't flood control for send in ADMIN_CONNS: send_msg = {"text": message} diff --git a/docker-env b/docker-env index 4da3990b1..373b4f28c 100644 --- a/docker-env +++ b/docker-env @@ -2,6 +2,6 @@ REPO=ajslater/codex IMAGE=ajslater/codex INSTALL_BASE_VERSION=python3.8.5-alpine3.12_0.1.0-3fb89fc RUNNABLE_BASE_VERSION=python3.8.5-alpine3.12_0.2.0-a88d3d9_0.1.0-3328e8e -PKG_VERSION=0.5.13 +PKG_VERSION=0.5.14 PUID=501 PGID=20 diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 8d8848e72..55ba0b7e0 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,6 +1,6 @@ { "name": "codex", - "version": "0.5.13", + "version": "0.5.14", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -3574,15 +3574,15 @@ "dev": true }, "@typescript-eslint/experimental-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.1.1.tgz", - "integrity": "sha512-jzYsNciHoa4Z3c1URtmeT/bamYm8Dwfw6vuN3WHIE/BXb1iC4KveAnXDErTAZtPVxTYBaYn3n2gbt6F6D2rm1A==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.2.0.tgz", + "integrity": "sha512-5BBj6BjgHEndBaQQpUVzRIPERz03LBc0MCQkHwUaH044FJFL08SwWv/sQftk7gf0ShZ2xZysz0LTwCwNt4Xu3w==", "dev": true, "requires": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.1.1", - "@typescript-eslint/types": "4.1.1", - "@typescript-eslint/typescript-estree": "4.1.1", + "@typescript-eslint/scope-manager": "4.2.0", + "@typescript-eslint/types": "4.2.0", + "@typescript-eslint/typescript-estree": "4.2.0", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" }, @@ -3617,29 +3617,29 @@ } }, "@typescript-eslint/scope-manager": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.1.1.tgz", - "integrity": "sha512-0W8TTobCvIIQ2FsrYTffyZGAAFUyIbEHq5EYJb1m7Rpd005jrnOvKOo8ywCLhs/Bm17C+KsrUboBvBAARQVvyA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.2.0.tgz", + "integrity": "sha512-Tb402cxxObSxWIVT+PnBp5ruT2V/36yj6gG4C9AjkgRlZpxrLAzWDk3neen6ToMBGeGdxtnfFLoJRUecGz9mYQ==", "dev": true, "requires": { - "@typescript-eslint/types": "4.1.1", - "@typescript-eslint/visitor-keys": "4.1.1" + "@typescript-eslint/types": "4.2.0", + "@typescript-eslint/visitor-keys": "4.2.0" } }, "@typescript-eslint/types": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.1.1.tgz", - "integrity": "sha512-zrBiqOKYerMTllKcn+BP+i1b7LW/EbMMYytroXMxUTvFPn1smkCu0D7lSAx29fTUO4jnwV0ljSvYQtn2vNrNxA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.2.0.tgz", + "integrity": "sha512-xkv5nIsxfI/Di9eVwN+G9reWl7Me9R5jpzmZUch58uQ7g0/hHVuGUbbn4NcxcM5y/R4wuJIIEPKPDb5l4Fdmwg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.1.1.tgz", - "integrity": "sha512-2AUg5v0liVBsqbGxBphbJ0QbGqSRVaF5qPoTPWcxop+66vMdU1h4CCvHxTC47+Qb+Pr4l2RhXDd41JNpwcQEKw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.2.0.tgz", + "integrity": "sha512-iWDLCB7z4MGkLipduF6EOotdHNtgxuNKnYD54nMS/oitFnsk4S3S/TE/UYXQTra550lHtlv9eGmp+dvN9pUDtA==", "dev": true, "requires": { - "@typescript-eslint/types": "4.1.1", - "@typescript-eslint/visitor-keys": "4.1.1", + "@typescript-eslint/types": "4.2.0", + "@typescript-eslint/visitor-keys": "4.2.0", "debug": "^4.1.1", "globby": "^11.0.1", "is-glob": "^4.0.1", @@ -3776,12 +3776,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.1.1.tgz", - "integrity": "sha512-/EOOXbA2ferGLG6RmCHEQ0lTTLkOlXYDgblCmQk3tIU7mTPLm4gKhFMeeUSe+bcchTUsKeCk8xcpbop5Zr/8Rw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.2.0.tgz", + "integrity": "sha512-WIf4BNOlFOH2W+YqGWa6YKLcK/EB3gEj2apCrqLw6mme1RzBy0jtJ9ewJgnrZDB640zfnv8L+/gwGH5sYp/rGw==", "dev": true, "requires": { - "@typescript-eslint/types": "4.1.1", + "@typescript-eslint/types": "4.2.0", "eslint-visitor-keys": "^2.0.0" }, "dependencies": { @@ -9309,9 +9309,9 @@ } }, "eslint-config-prettier": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", - "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.12.0.tgz", + "integrity": "sha512-9jWPlFlgNwRUYVoujvWTQ1aMO8o6648r+K7qU7K5Jmkbyqav1fuEZC0COYpGBxyiAJb65Ra9hrmFx19xRGwXWw==", "dev": true, "requires": { "get-stdin": "^6.0.0" @@ -9415,9 +9415,9 @@ } }, "eslint-plugin-jest": { - "version": "24.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.0.1.tgz", - "integrity": "sha512-8tYFDqOHGr7vVfdVYspmlV4sRBTylrM4gSLgkGKlO6F+djDOEJ+tEU7I50smUs7AIvFnNZutXUQAMgI9s9N6xQ==", + "version": "24.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.0.2.tgz", + "integrity": "sha512-DSBLNpkKDOpUJQkTGSs5sVJWsu0nDyQ2rYxkr0Eh7nrkc5bMUr/dlDbtTj3l8y6UaCVsem6rryF1OZrKnz1S5g==", "dev": true, "requires": { "@typescript-eslint/experimental-utils": "^4.0.1" @@ -9634,9 +9634,9 @@ } }, "eslint-plugin-vue": { - "version": "7.0.0-beta.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.0.0-beta.3.tgz", - "integrity": "sha512-/p23IRPN9gFNN7dzesrctt06Kvs9E3VRB8BGIAPSEaQNk5yhlKUzntPARjUpsTWW+DQg0mqglZptfkUJK4+4EQ==", + "version": "7.0.0-beta.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.0.0-beta.4.tgz", + "integrity": "sha512-yb8Kki8b94a3A1sGum9TyVAkvPfKGPzWfZcXRmA2Tylt7TRi+b6mOtn1o6kM3NWatBs5gcGiCrH033DDPn0Msw==", "dev": true, "requires": { "eslint-utils": "^2.1.0", @@ -20415,9 +20415,9 @@ } }, "vue-router": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.4.3.tgz", - "integrity": "sha512-BADg1mjGWX18Dpmy6bOGzGNnk7B/ZA0RxuA6qedY/YJwirMfKXIDzcccmHbQI0A6k5PzMdMloc0ElHfyOoX35A==" + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.4.4.tgz", + "integrity": "sha512-qFfwwLvxUYq+iDJ0UoE8HMnuZEDtIDA+p573brVMb7NZr0t1vhMeMWDTvgF2b8MqAFOc77bNOTSSwYcR4pCZlg==" }, "vue-style-loader": { "version": "4.1.2", diff --git a/frontend/package.json b/frontend/package.json index 270ce750f..e96282789 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "codex", - "version": "0.5.13", + "version": "0.5.14", "private": true, "description": "ui for codex api", "scripts": { @@ -17,7 +17,7 @@ "normalize.css": "^8.0.1", "reconnecting-websocket": "^4.4.0", "vue": "^2.6.11", - "vue-router": "^3.4.3", + "vue-router": "^3.4.4", "vue2-filters": "^0.11.0", "vuetify": "^2.3.10", "vuex": "^3.5.1" @@ -36,11 +36,11 @@ "babel-eslint": "^10.1.0", "eslint": "^7.9.0", "eslint-config-adjunct": "^4.8.7", - "eslint-config-prettier": "^6.11.0", + "eslint-config-prettier": "^6.12.0", "eslint-plugin-array-func": "^3.1.7", "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-html": "^6.1.0", - "eslint-plugin-jest": "^24.0.1", + "eslint-plugin-jest": "^24.0.2", "eslint-plugin-jest-async": "^1.0.3", "eslint-plugin-json": "^2.1.2", "eslint-plugin-json-format": "^2.0.1", @@ -58,8 +58,8 @@ "eslint-plugin-simple-import-sort": "^5.0.3", "eslint-plugin-sonarjs": "^0.5.0", "eslint-plugin-switch-case": "^1.1.2", - "eslint-plugin-unicorn": "^21.0.0", - "eslint-plugin-vue": "^7.0.0-beta.3", + "eslint-plugin-unicorn": "^22.0.0", + "eslint-plugin-vue": "^7.0.0-beta.4", "eslint-plugin-vue-scoped-css": "^1.0.0", "prettier": "^2.1.2", "prettier-plugin-package": "^1.0.0", diff --git a/frontend/src/api/auth.js b/frontend/src/api/v1/auth.js similarity index 100% rename from frontend/src/api/auth.js rename to frontend/src/api/v1/auth.js diff --git a/frontend/src/api/base.js b/frontend/src/api/v1/base.js similarity index 100% rename from frontend/src/api/base.js rename to frontend/src/api/v1/base.js diff --git a/frontend/src/api/browser.js b/frontend/src/api/v1/browser.js similarity index 100% rename from frontend/src/api/browser.js rename to frontend/src/api/v1/browser.js diff --git a/frontend/src/api/metadata.js b/frontend/src/api/v1/metadata.js similarity index 63% rename from frontend/src/api/metadata.js rename to frontend/src/api/v1/metadata.js index 919377731..a6d209373 100644 --- a/frontend/src/api/metadata.js +++ b/frontend/src/api/v1/metadata.js @@ -1,9 +1,10 @@ import { ajax, API_PREFIX } from "./base"; const COMIC_BASE = "/comic"; +const METADATA_BASE = "/metadata"; -const getComicMetadata = (pk) => { - return ajax("get", `${COMIC_BASE}/${pk}/metadata`); +const getComicMetadata = (group, pk) => { + return ajax("get", `${METADATA_BASE}/${group}/${pk}`); }; export const getDownloadURL = (pk) => { diff --git a/frontend/src/api/reader.js b/frontend/src/api/v1/reader.js similarity index 100% rename from frontend/src/api/reader.js rename to frontend/src/api/v1/reader.js diff --git a/frontend/src/browser.vue b/frontend/src/browser.vue index 062e3bcd6..32b2ab245 100644 --- a/frontend/src/browser.vue +++ b/frontend/src/browser.vue @@ -245,14 +245,20 @@ import { mdiArrowUp, mdiCloseCircle, mdiDotsVertical } from "@mdi/js"; import { mapGetters, mapState } from "vuex"; -import { ADMIN_URL } from "@/api/auth"; -import { FAILED_IMPORT_URL, getSocket } from "@/api/browser"; -import { getVolumeName } from "@/comic-name"; +import { ADMIN_URL } from "@/api/v1/auth"; +import { FAILED_IMPORT_URL, getSocket } from "@/api/v1/browser"; +import WS_MESSAGES from "@/choices/websocketMessages.json"; import AuthDialog from "@/components/auth-dialog"; import BrowseCard from "@/components/browse-card"; +import { getVolumeName } from "@/components/comic-name"; import FilterSubMenu from "@/components/filter-sub-menu"; import PlaceholderLoading from "@/components/placeholder-loading"; +const SCAN_DONE_MSGS = new Set([ + WS_MESSAGES.admin.SCAN_DONE, + WS_MESSAGES.admin.FAILED_IMPORTS, +]); + export default { name: "Browser", components: { @@ -465,14 +471,14 @@ export default { }, websocketListener: function (event) { console.debug("websocket push:", event.data); - if (event.data === "libraryChanged") { + if (event.data === WS_MESSAGES.user.LIBRARY_CHANGED) { this.$store.dispatch("browser/getBrowseObjects"); } else if (this.isAdmin) { - if (event.data === "scanLibrary") { + if (event.data === WS_MESSAGES.admin.SCAN_LIBRARY) { this.setScanNotify(true); - } else if (["scanDone", "failedImports"].includes(event.data)) { + } else if (SCAN_DONE_MSGS.has(event.data)) { this.setScanNotify(false); - if (event.data === "failedImports") { + if (event.data === WS_MESSAGES.admin.FAILED_IMPORTS) { this.failedImportsNotify = true; } } diff --git a/frontend/src/choices/websocketMessages.json b/frontend/src/choices/websocketMessages.json new file mode 100644 index 000000000..14b1bfdb2 --- /dev/null +++ b/frontend/src/choices/websocketMessages.json @@ -0,0 +1,10 @@ +{ + "user": { + "LIBRARY_CHANGED": "libraryChanged" + }, + "admin": { + "SCAN_LIBRARY": "scanLibrary", + "FAILED_IMPORTS": "failedImports", + "SCAN_DONE": "scanDone" + } +} diff --git a/frontend/src/components/auth-dialog.vue b/frontend/src/components/auth-dialog.vue index 60a90a18b..3cbfa6d8b 100644 --- a/frontend/src/components/auth-dialog.vue +++ b/frontend/src/components/auth-dialog.vue @@ -93,7 +93,7 @@ - - diff --git a/frontend/src/components/browse-container-menu.vue b/frontend/src/components/browse-container-menu.vue index cb53994c7..779f18fd8 100644 --- a/frontend/src/components/browse-container-menu.vue +++ b/frontend/src/components/browse-container-menu.vue @@ -17,7 +17,7 @@ diff --git a/frontend/src/components/metadata-checkbox.vue b/frontend/src/components/metadata-checkbox.vue new file mode 100644 index 000000000..79bc4e327 --- /dev/null +++ b/frontend/src/components/metadata-checkbox.vue @@ -0,0 +1,52 @@ + + + + diff --git a/frontend/src/components/metadata-combobox.vue b/frontend/src/components/metadata-combobox.vue index 67cb4fcb7..856859cdb 100644 --- a/frontend/src/components/metadata-combobox.vue +++ b/frontend/src/components/metadata-combobox.vue @@ -1,8 +1,8 @@ diff --git a/frontend/src/components/browser-filter-select.vue b/frontend/src/components/browser-filter-select.vue index f0906d3c8..419f6316d 100644 --- a/frontend/src/components/browser-filter-select.vue +++ b/frontend/src/components/browser-filter-select.vue @@ -4,6 +4,7 @@ v-model="bookmarkFilter" :items="bookmarkChoices" class="toolbarSelect filterSelect" + :label="label" dense hide-details="auto" ripple @@ -14,6 +15,8 @@ }" :prepend-inner-icon="filterInnerIcon" @click:prepend-inner="clearFilters" + @focus="label = 'filter by'" + @blur="label = ''" > + + diff --git a/frontend/src/components/browser-pagination-toolbar.vue b/frontend/src/components/browser-pagination-toolbar.vue index e332c9bc4..ceeb0bffd 100644 --- a/frontend/src/components/browser-pagination-toolbar.vue +++ b/frontend/src/components/browser-pagination-toolbar.vue @@ -28,22 +28,12 @@ export default { }, computed: { ...mapState("browser", { - numPages: (state) => +state.numPages, + numPages: (state) => Number(state.numPages), }), }, methods: { routeToPage: function (page) { - if (page === this.$route.params.page) { - console.debug("Redundant navigation. Noop."); - return; - } - const params = { ...this.$route.params }; - params.page = page; - const route = { - name: this.$route.name, - params: params, - }; - this.$router.push(route); + this.$store.dispatch("browser/routeToPage", page); }, }, }; diff --git a/frontend/src/components/browser-root-group-select.vue b/frontend/src/components/browser-root-group-select.vue deleted file mode 100644 index 70dba976e..000000000 --- a/frontend/src/components/browser-root-group-select.vue +++ /dev/null @@ -1,42 +0,0 @@ - - - - -// style is handled in browser-filter-toolbar.vue diff --git a/frontend/src/components/browser-search-field.vue b/frontend/src/components/browser-search-field.vue new file mode 100644 index 000000000..8b9a6fd29 --- /dev/null +++ b/frontend/src/components/browser-search-field.vue @@ -0,0 +1,64 @@ + + + diff --git a/frontend/src/components/browser-settings-menu.vue b/frontend/src/components/browser-settings-menu.vue deleted file mode 100644 index e75e5b7ed..000000000 --- a/frontend/src/components/browser-settings-menu.vue +++ /dev/null @@ -1,58 +0,0 @@ - - - - - diff --git a/frontend/src/components/browser-settings-dialog.vue b/frontend/src/components/browser-settings-panel.vue similarity index 56% rename from frontend/src/components/browser-settings-dialog.vue rename to frontend/src/components/browser-settings-panel.vue index a573000bf..1c96fa311 100644 --- a/frontend/src/components/browser-settings-dialog.vue +++ b/frontend/src/components/browser-settings-panel.vue @@ -1,50 +1,51 @@ @@ -80,7 +71,13 @@ export default { .settingsGroupCaption { color: gray; } -#browserSettingsDialog { - padding: 20px; +.settingsCheckbox { + padding-left: 5px; +} +#browserSettings { + padding-left: 15px; +} +.openInNewIcon { + color: gray; } diff --git a/frontend/src/components/browser-sort-by-select.vue b/frontend/src/components/browser-sort-by-select.vue deleted file mode 100644 index 7ea422bac..000000000 --- a/frontend/src/components/browser-sort-by-select.vue +++ /dev/null @@ -1,78 +0,0 @@ - - - - - diff --git a/frontend/src/components/browser-title-toolbar.vue b/frontend/src/components/browser-title-toolbar.vue index b504a5361..84a61e4f3 100644 --- a/frontend/src/components/browser-title-toolbar.vue +++ b/frontend/src/components/browser-title-toolbar.vue @@ -51,17 +51,16 @@ export default { return this.upRoute && "group" in this.upRoute; }, longBrowserTitlePrefix: function () { - const group = this.$route.params.group; - if (group !== "f") { - return null; + if (this.$route.params.group === "f") { + return this.browserTitle.parentName; } - return this.browserTitle.parentName; + return ""; }, longBrowseTitleMain: function () { let browserTitle; const group = this.$route.params.group; const { parentName, groupName, groupCount } = this.browserTitle; - if (+this.$route.params.pk === 0) { + if (Number(this.$route.params.pk) === 0) { browserTitle = "All"; } else if (group === "i") { browserTitle = `${parentName} ${groupName}`; diff --git a/frontend/src/components/browser-top-group-select.vue b/frontend/src/components/browser-top-group-select.vue new file mode 100644 index 000000000..ffaf6dc07 --- /dev/null +++ b/frontend/src/components/browser-top-group-select.vue @@ -0,0 +1,50 @@ + + + + +// #topGroupSelect style is handled in browser-filter-toolbar.vue diff --git a/frontend/src/components/comic-name.js b/frontend/src/components/comic-name.js index bb9a167c6..cd1ea72d8 100644 --- a/frontend/src/components/comic-name.js +++ b/frontend/src/components/comic-name.js @@ -1,15 +1,18 @@ export const getVolumeName = function (volume) { let volumeName; - if (volume == "" || volume == null) { - volume = 1; + if (!volume) { + volumeName = ""; + } else { + volumeName = + volume.length === 4 && !Number.isNaN(volume) + ? " (" + volume + ")" + : " v" + volume; } - volumeName = - volume.length === 4 && !isNaN(volume) ? " (" + volume + ")" : " v" + volume; return volumeName; }; export const formattedIssue = function (decimalIssue) { - if (decimalIssue == null) { + if (decimalIssue === undefined || decimalIssue === null) { return; } const intIssue = Math.floor(decimalIssue); diff --git a/frontend/src/components/filter-sub-menu.vue b/frontend/src/components/filter-sub-menu.vue index 6884a763f..d30958839 100644 --- a/frontend/src/components/filter-sub-menu.vue +++ b/frontend/src/components/filter-sub-menu.vue @@ -74,6 +74,7 @@ export default { required: true, }, }, + emits: ["sub-menu-click"], data() { return { mdiChevronLeft, @@ -93,7 +94,7 @@ export default { filterMode: (state) => state.filterMode, }), vuetifyItems: function () { - return toVuetifyItems(null, this.formChoices, this.query); + return toVuetifyItems(undefined, this.formChoices, this.query); }, filter: { get() { @@ -111,15 +112,19 @@ export default { const words = this.name.split("_"); let title = ""; for (const index in words) { - // Capitalize words - const word = words[index]; - const capWord = - word === "ltr" ? "LTR" : word.charAt(0).toUpperCase() + word.slice(1); - // Append to title - if (index) { - title += " "; + if (Object.prototype.hasOwnProperty.call(words, index)) { + // Capitalize words + const word = words[index]; + const capWord = + word === "ltr" + ? "LTR" + : word.charAt(0).toUpperCase() + word.slice(1); + // Append to title + if (index) { + title += " "; + } + title += capWord; } - title += capWord; } return title; }, @@ -156,6 +161,6 @@ export default { .filterHeader { } .filterGroup { - max-height: 90vh; /* has to be less than the menu height */ + max-height: 80vh; /* has to be less than the menu height */ } diff --git a/frontend/src/components/metadata-autocomplete.vue b/frontend/src/components/metadata-autocomplete.vue deleted file mode 100644 index ff0bcfa16..000000000 --- a/frontend/src/components/metadata-autocomplete.vue +++ /dev/null @@ -1,60 +0,0 @@ - - - - - diff --git a/frontend/src/components/metadata-checkbox.vue b/frontend/src/components/metadata-checkbox.vue index b3929c8ba..a3da14105 100644 --- a/frontend/src/components/metadata-checkbox.vue +++ b/frontend/src/components/metadata-checkbox.vue @@ -1,13 +1,11 @@ - - diff --git a/frontend/src/components/metadata-combobox.vue b/frontend/src/components/metadata-combobox.vue deleted file mode 100644 index e8f70d0cb..000000000 --- a/frontend/src/components/metadata-combobox.vue +++ /dev/null @@ -1,59 +0,0 @@ - - - - - diff --git a/frontend/src/components/metadata-dialog.vue b/frontend/src/components/metadata-dialog.vue index 21c93962a..1ed0b2383 100644 --- a/frontend/src/components/metadata-dialog.vue +++ b/frontend/src/components/metadata-dialog.vue @@ -6,7 +6,7 @@ class="metadataDialog" > @@ -32,222 +32,129 @@ id="topCloseButton" title="Close Metadata (esc)" ripple - @click="dialogClosed()" + @click="dialog = false" >x - - - -
- + + +
+ -
-
- + -
- -
- -
- - + + - - + + - -
- - Read {{ md.bookmark }} of {{ md.page_count }} pages - ({{ Math.round(md.progress) }}%) - Finished, - - - {{ md.size | bytes }} - + + +
+
+
+ + +
- - - - - - - - - -
Created at{{ formatDatetime(md.created_at) }}
Updated at{{ formatDatetime(md.updated_at) }}
- Path: {{ md.path }} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Creators

-
RolePerson
- - - -
-
- - -
+
+
+
+ + +
+ + +
+
+ + +
+
+ + + +
+
+ + + + + + + +
+
+ + + + + +
+
+ + + +