diff --git a/OpenMarketplace/.babelrc b/OpenMarketplace/.babelrc new file mode 100644 index 0000000..e563a62 --- /dev/null +++ b/OpenMarketplace/.babelrc @@ -0,0 +1,15 @@ +{ + "presets": [ + ["env", { + "targets": { + "node": "6" + }, + "useBuiltIns": true + }] + ], + "plugins": [ + ["transform-object-rest-spread", { + "useBuiltIns": true + }] + ] +} diff --git a/OpenMarketplace/.docker/nginx/conf.d/default.conf b/OpenMarketplace/.docker/nginx/conf.d/default.conf new file mode 100644 index 0000000..41eb06d --- /dev/null +++ b/OpenMarketplace/.docker/nginx/conf.d/default.conf @@ -0,0 +1,40 @@ +server { + root /var/www/tests/Application/public; + + location / { + # try to serve file directly, fallback to index.php + try_files $uri /index.php$is_args$args; + } + + location ~ ^/index\.php(/|$) { + # Comment the next line and uncomment the next to enable dynamic resolution (incompatible with Kubernetes) + fastcgi_pass php:9000; + #resolver 127.0.0.11; + #set $upstream_host php; + #fastcgi_pass $upstream_host:9000; + + fastcgi_split_path_info ^(.+\.php)(/.*)$; + include fastcgi_params; + # When you are using symlinks to link the document root to the + # current version of your application, you should pass the real + # application path instead of the path to the symlink to PHP + # FPM. + # Otherwise, PHP's OPcache may not properly detect changes to + # your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126 + # for more information). + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + fastcgi_param DOCUMENT_ROOT $realpath_root; + # Prevents URIs that include the front controller. This will 404: + # http://domain.tld/index.php/some-path + # Remove the internal directive to allow URIs like this + internal; + } + + # return 404 for all other php files not matching the front controller + # this prevents access to other php files you don't want to be accessible. + location ~ \.php$ { + return 404; + } + + client_max_body_size 6m; +} diff --git a/OpenMarketplace/.docker/nodejs/docker-entrypoint.sh b/OpenMarketplace/.docker/nodejs/docker-entrypoint.sh new file mode 100644 index 0000000..9652169 --- /dev/null +++ b/OpenMarketplace/.docker/nodejs/docker-entrypoint.sh @@ -0,0 +1,18 @@ +#!/bin/sh +set -e + +# first arg is `-f` or `--some-option` +if [ "${1#-}" != "$1" ]; then + set -- node "$@" +fi + +if [ "$1" = 'node' ] || [ "$1" = 'yarn' ]; then + yarn install + + >&2 echo "Waiting for PHP to be ready..." + until nc -z "$PHP_HOST" "$PHP_PORT"; do + sleep 1 + done +fi + +exec "$@" diff --git a/OpenMarketplace/.docker/php/docker-entrypoint.sh b/OpenMarketplace/.docker/php/docker-entrypoint.sh new file mode 100644 index 0000000..b2c57cd --- /dev/null +++ b/OpenMarketplace/.docker/php/docker-entrypoint.sh @@ -0,0 +1,43 @@ +#!/bin/sh +set -e + +pluginDirectory='/var/www'; +pluginApplicationDirectory='/var/www/tests/Application'; + +# first arg is `-f` or `--some-option` +if [ "${1#-}" != "$1" ]; then + set -- php-fpm "$@" +fi + +if [ "$1" = 'php-fpm' ] || [ "$1" = 'bin/console' ]; then + mkdir -p var/cache var/log public/media/image + setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var public + setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var public + + if [ "$APP_ENV" != 'prod' ]; then + composer install --prefer-dist --no-progress --no-interaction; + cd $pluginDirectory && composer install --prefer-dist --no-progress --no-interaction; + cd $pluginApplicationDirectory; + fi + + echo "Waiting for db to be ready..." + ATTEMPTS_LEFT_TO_REACH_DATABASE=60 + + cd $pluginApplicationDirectory; + + until [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ] || DATABASE_ERROR=$(php bin/console dbal:run-sql "SELECT 1" 2>&1); do + if [ $? -eq 255 ]; then + # If the Doctrine command exits with 255, an unrecoverable error occurred + ATTEMPTS_LEFT_TO_REACH_DATABASE=0 + break + fi + sleep 1 + ATTEMPTS_LEFT_TO_REACH_DATABASE=$((ATTEMPTS_LEFT_TO_REACH_DATABASE - 1)) + echo "Still waiting for db to be ready... Or maybe the db is not reachable. $ATTEMPTS_LEFT_TO_REACH_DATABASE attempts left" + done + + php bin/console doctrine:database:create --if-not-exists; + php bin/console doctrine:schema:update -f; +fi + +exec docker-php-entrypoint "$@" diff --git a/OpenMarketplace/.docker/php/docker-healthcheck.sh b/OpenMarketplace/.docker/php/docker-healthcheck.sh new file mode 100644 index 0000000..f15b998 --- /dev/null +++ b/OpenMarketplace/.docker/php/docker-healthcheck.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -e + +export SCRIPT_NAME=/ping +export SCRIPT_FILENAME=/ping +export REQUEST_METHOD=GET + +if cgi-fcgi -bind -connect 127.0.0.1:9000; then + exit 0 +fi + +exit 1 diff --git a/OpenMarketplace/.docker/php/php-cli.ini b/OpenMarketplace/.docker/php/php-cli.ini new file mode 100644 index 0000000..cbfffc7 --- /dev/null +++ b/OpenMarketplace/.docker/php/php-cli.ini @@ -0,0 +1,16 @@ +apc.enable_cli = 1 +date.timezone = UTC +opcache.enable_cli = 1 +session.auto_start = Off +short_open_tag = Off + +# http://symfony.com/doc/current/performance.html +opcache.interned_strings_buffer = 16 +opcache.max_accelerated_files = 20000 +opcache.memory_consumption = 256 +realpath_cache_size = 4096K +realpath_cache_ttl = 600 + +memory_limit = 2G +post_max_size = 6M +upload_max_filesize = 5M diff --git a/OpenMarketplace/.docker/php/php.ini b/OpenMarketplace/.docker/php/php.ini new file mode 100644 index 0000000..f36f9b2 --- /dev/null +++ b/OpenMarketplace/.docker/php/php.ini @@ -0,0 +1,15 @@ +apc.enable_cli = 1 +date.timezone = UTC +opcache.enable_cli = 1 +session.auto_start = Off +short_open_tag = Off + +# http://symfony.com/doc/current/performance.html +opcache.interned_strings_buffer = 16 +opcache.max_accelerated_files = 20000 +opcache.memory_consumption = 256 +realpath_cache_size = 4096K +realpath_cache_ttl = 600 + +post_max_size = 6M +upload_max_filesize = 5M diff --git a/OpenMarketplace/.dockerignore b/OpenMarketplace/.dockerignore new file mode 100644 index 0000000..81d9a54 --- /dev/null +++ b/OpenMarketplace/.dockerignore @@ -0,0 +1,32 @@ +**/*.log +**/*.md +**/*.php~ +**/._* +**/.dockerignore +**/.DS_Store +**/.git/ +**/.gitattributes +**/.github +**/.gitignore +**/.gitkeep +**/.gitmodules +**/.idea +**/Dockerfile +**/Thumbs.db +**/docker-compose*.yaml +**/docker-compose*.yml +.editorconfig +.php_cs.cache +.travis.yml +composer.phar +docker/mysql/data/ +etc/build/* +node_modules/ +var/* +vendor/ +public/assets/ +public/build/ +public/bundles/ +public/css/ +public/js/ +public/media/ diff --git a/OpenMarketplace/.env b/OpenMarketplace/.env new file mode 100644 index 0000000..ef1cfe3 --- /dev/null +++ b/OpenMarketplace/.env @@ -0,0 +1,46 @@ +# This file is a "template" of which env vars needs to be defined in your configuration or in an .env file +# Set variables here that may be different on each deployment target of the app, e.g. development, staging, production. +# https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration + +###> symfony/framework-bundle ### +APP_ENV=dev +APP_DEBUG=1 +APP_SECRET=EDITME +###< symfony/framework-bundle ### + +###> doctrine/doctrine-bundle ### +# Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url +# For a sqlite database, use: "sqlite:///%kernel.project_dir%/var/data.db" +# Set "serverVersion" to your server version to avoid edge-case exceptions and extra database calls + +DATABASE_URL=mysql://root@127.0.0.1/open_marketplace_%kernel.environment%?serverVersion=5.7 + +###< doctrine/doctrine-bundle ### + +###> lexik/jwt-authentication-bundle ### +JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem +JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem +JWT_PASSPHRASE=acme_plugin_development +###< lexik/jwt-authentication-bundle ### + +###> symfony/swiftmailer-bundle ### +# For Gmail as a transport, use: "gmail://username:password@localhost" +# For a generic SMTP server, use: "smtp://localhost:25?encryption=&auth_mode=" +# Delivery is disabled by default via "null://localhost" +MAILER_URL=null://localhost +###< symfony/swiftmailer-bundle ### + +###> symfony/messenger ### +# Choose one of the transports below +# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages +MESSENGER_TRANSPORT_DSN=sync:// +# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages +###< symfony/messenger ### + +LOGO_DIRECTORY=media/image/logo/ +VENDOR_PRODUCTS_LIMITS=9,18,27 +DEFAULT_VENDOR_PRODUCTS_LIMIT=9 +MESSAGES_FILE_UPLOAD_DIRECTORY=uploads/message_files +# Vendor commission settings +DEFAULT_VENDOR_COMMISSION=10 +DEFAULT_VENDOR_COMMISSION_TYPE=gross diff --git a/OpenMarketplace/.env.prod b/OpenMarketplace/.env.prod new file mode 100644 index 0000000..e69de29 diff --git a/OpenMarketplace/.env.test b/OpenMarketplace/.env.test new file mode 100644 index 0000000..4350b9a --- /dev/null +++ b/OpenMarketplace/.env.test @@ -0,0 +1,46 @@ +# This file is a "template" of which env vars needs to be defined in your configuration or in an .env file +# Set variables here that may be different on each deployment target of the app, e.g. development, staging, production. +# https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration + +###> symfony/framework-bundle ### +APP_ENV=dev +APP_DEBUG=1 +APP_SECRET=EDITME +###< symfony/framework-bundle ### + +###> doctrine/doctrine-bundle ### +# Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url +# For a sqlite database, use: "sqlite:///%kernel.project_dir%/var/data.db" +# Set "serverVersion" to your server version to avoid edge-case exceptions and extra database calls + +DATABASE_URL=mysql://root@127.0.0.1/open_marketplace_%kernel.environment%?serverVersion=5.7 + +###< doctrine/doctrine-bundle ### + +###> lexik/jwt-authentication-bundle ### +JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private-test.pem +JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public-test.pem +JWT_PASSPHRASE=acme_plugin_development +###< lexik/jwt-authentication-bundle ### + +###> symfony/swiftmailer-bundle ### +# For Gmail as a transport, use: "gmail://username:password@localhost" +# For a generic SMTP server, use: "smtp://localhost:25?encryption=&auth_mode=" +# Delivery is disabled by default via "null://localhost" +#MAILER_URL=smtp://localhost +###< symfony/swiftmailer-bundle ### + +###> symfony/messenger ### +# Choose one of the transports below +# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages +MESSENGER_TRANSPORT_DSN=sync:// +# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages +###< symfony/messenger ### + +LOGO_DIRECTORY=media/image/logo/ +VENDOR_PRODUCTS_LIMITS=9,18,27 +DEFAULT_VENDOR_PRODUCTS_LIMIT=9 +MESSAGES_FILE_UPLOAD_DIRECTORY=uploads/message_files + +DEFAULT_VENDOR_COMMISSION=5 +DEFAULT_VENDOR_COMMISSION_TYPE=net diff --git a/OpenMarketplace/.eslintrc.js b/OpenMarketplace/.eslintrc.js new file mode 100644 index 0000000..dfddb25 --- /dev/null +++ b/OpenMarketplace/.eslintrc.js @@ -0,0 +1,20 @@ +module.exports = { + extends: 'airbnb-base', + env: { + node: true, + }, + rules: { + 'object-shorthand': ['error', 'always', { + avoidQuotes: true, + avoidExplicitReturnArrows: true, + }], + 'function-paren-newline': ['error', 'consistent'], + 'max-len': ['warn', 120, 2, { + ignoreUrls: true, + ignoreComments: false, + ignoreRegExpLiterals: true, + ignoreStrings: true, + ignoreTemplateLiterals: true, + }], + }, +}; diff --git a/OpenMarketplace/.github/CODEOWNERS b/OpenMarketplace/.github/CODEOWNERS new file mode 100644 index 0000000..7970828 --- /dev/null +++ b/OpenMarketplace/.github/CODEOWNERS @@ -0,0 +1 @@ +* @BitBagCommerce diff --git a/OpenMarketplace/.github/workflows/build.yml b/OpenMarketplace/.github/workflows/build.yml new file mode 100644 index 0000000..e860f3e --- /dev/null +++ b/OpenMarketplace/.github/workflows/build.yml @@ -0,0 +1,193 @@ +name: Build + +on: + push: + branches-ignore: + - 'dependabot/**' + pull_request: ~ + release: + types: [created] +# schedule: +# - +# cron: "0 1 * * 6" # Run at 1am every Saturday + workflow_dispatch: ~ + +jobs: + tests: + runs-on: ubuntu-20.04 + + name: "Sylius ${{ matrix.sylius }}, PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, MySQL ${{ matrix.mysql }}" + + strategy: + fail-fast: false + matrix: + php: ["8.0"] + symfony: ["^5.2"] + sylius: ["^1.11.12"] + node: ["14.x"] + mysql: ["8.0"] + + env: + APP_ENV: test + DATABASE_URL: "mysql://root:root@127.0.0.1/sylius?serverVersion=${{ matrix.mysql }}" + + steps: + - + uses: actions/checkout@v2 + + - + name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "${{ matrix.php }}" + extensions: intl + tools: symfony + coverage: none + + - + name: Setup Node + uses: actions/setup-node@v1 + with: + node-version: "${{ matrix.node }}" + + - + name: Shutdown default MySQL + run: sudo service mysql stop + + - + name: Setup MySQL + uses: mirromutth/mysql-action@v1.1 + with: + mysql version: "${{ matrix.mysql }}" + mysql root password: "root" + + - + name: Output PHP version for Symfony CLI + run: php -v | head -n 1 | awk '{ print $2 }' > .php-version + + - + name: Install certificates + run: symfony server:ca:install + + - + name: Run Chrome Headless + run: google-chrome-stable --enable-automation --disable-background-networking --no-default-browser-check --no-first-run --disable-popup-blocking --disable-default-apps --allow-insecure-localhost --disable-translate --disable-extensions --no-sandbox --enable-features=Metal --headless --remote-debugging-port=9222 --window-size=2880,1800 --proxy-server='direct://' --proxy-bypass-list='*' http://127.0.0.1 > /dev/null 2>&1 & + + - + name: Run webserver + run: (symfony server:start --port=8080 --dir=public --daemon) + + - + name: Get Composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - + name: Cache Composer + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.json **/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php-${{ matrix.php }}-composer- + - + name: Restrict Symfony version + if: matrix.symfony != '' + run: | + composer global config --no-plugins allow-plugins.symfony/flex true + composer global require --no-progress --no-scripts --no-plugins "symfony/flex:^1.10" + composer config extra.symfony.require "${{ matrix.symfony }}" + - + name: Restrict Sylius version + if: matrix.sylius != '' + run: composer require "sylius/sylius:${{ matrix.sylius }}" --no-update --no-scripts --no-interaction + + - + name: Install PHP dependencies + run: composer install --no-interaction + + - + name: Run ECS + run: vendor/bin/ecs check src spec tests + + - + name: Get Yarn cache directory + id: yarn-cache + run: echo "::set-output name=dir::$(yarn cache dir)" + + - + name: Cache Yarn + uses: actions/cache@v2 + with: + path: ${{ steps.yarn-cache.outputs.dir }} + key: ${{ runner.os }}-node-${{ matrix.node }}-yarn-${{ hashFiles('**/package.json **/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-node-${{ matrix.node }}-yarn- + - + name: Install JS dependencies + run: yarn install + + - + name: Prepare test application database + run: | + (bin/console doctrine:database:create -vvv) + (bin/console doctrine:schema:create -vvv) + - + name: Prepare test application assets + run: | + (bin/console assets:install public -vvv) + (yarn encore prod) + - + name: Prepare test application cache + run: (bin/console cache:warmup -vvv) + + - + name: Load fixtures in test application + run: (bin/fixtures) + + - + name: Validate composer.json + run: composer validate --ansi --strict + + - + name: Validate database schema + run: (bin/console doctrine:schema:validate) + + - + name: Run PHPStan + run: vendor/bin/phpstan analyse -c phpstan.neon -l 8 src/ + + - + name: Run PHPSpec + run: vendor/bin/phpspec run --ansi -f progress --no-interaction + + + - + name: Run PHPUnit + run: vendor/bin/phpunit --colors=always + + - + name: Run Behat + run: vendor/bin/behat --colors --strict -vvv --no-interaction -f progress || vendor/bin/behat --colors --strict -vvv --no-interaction --rerun + + - + name: Upload Behat logs + uses: actions/upload-artifact@v2 + if: failure() + with: + name: Behat logs + path: etc/build/ + if-no-files-found: ignore + + - + name: Failed build Slack notification + uses: rtCamp/action-slack-notify@v2 + if: ${{ failure() && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') }} + env: + SLACK_CHANNEL: ${{ secrets.FAILED_BUILD_SLACK_CHANNEL }} + SLACK_COLOR: ${{ job.status }} + SLACK_ICON: https://github.com/rtCamp.png?size=48 + SLACK_MESSAGE: ':x:' + SLACK_TITLE: Failed build on ${{ github.event.repository.name }} repository + SLACK_USERNAME: ${{ secrets.FAILED_BUILD_SLACK_USERNAME }} + SLACK_WEBHOOK: ${{ secrets.FAILED_BUILD_SLACK_WEBHOOK }} \ No newline at end of file diff --git a/OpenMarketplace/.gitignore b/OpenMarketplace/.gitignore new file mode 100644 index 0000000..96179c1 --- /dev/null +++ b/OpenMarketplace/.gitignore @@ -0,0 +1,39 @@ +/vendor/ +/node_modules/ +/composer.lock + +/etc/build/* +!/etc/build/.gitignore + +/tests/Application/yarn.lock +/tests/Application/public/uploads +/.phpunit.result.cache +/behat.yml +/phpspec.yml +/phpunit.xml +.idea/ + +/public/assets +/public/build +/public/css +/public/js +/public/media/* +!/public/media/image/ +/public/media/image/* +!/public/media/image/.gitignore + +/node_modules + +###> symfony/framework-bundle ### + +.env.*.local +.env.local +.env.local.php +/public/bundles +/public/uploads/message_files +/var/ +###< symfony/framework-bundle ### + +###> symfony/web-server-bundle ### +/.web-server-pid +###< symfony/web-server-bundle ### diff --git a/OpenMarketplace/.phpspec/specification.tpl b/OpenMarketplace/.phpspec/specification.tpl new file mode 100644 index 0000000..04fc5d2 --- /dev/null +++ b/OpenMarketplace/.phpspec/specification.tpl @@ -0,0 +1,22 @@ +shouldHaveType(%subject_class%::class); + } +} diff --git a/OpenMarketplace/CODE_OF_CONDUCT.md b/OpenMarketplace/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..41ef3a7 --- /dev/null +++ b/OpenMarketplace/CODE_OF_CONDUCT.md @@ -0,0 +1,57 @@ + +# Project Code of Conduct + +Our project is dedicated to providing a welcoming and inclusive environment for all contributors, regardless of background or identity. +We believe that diversity and inclusivity are critical to the success of any open source project, and we are committed to creating a safe +and respectful space for collaboration. + +As contributors and maintainers of this project, we pledge to uphold the following values: + +## 1. Respect and Empathy + +We value all contributors and their ideas, and we are committed to treating everyone with respect and empathy. We will listen actively and +communicate constructively, using welcoming and inclusive language. + +## 2. Openness and Collaboration + +We welcome and encourage participation from everyone, regardless of their background or level of experience. We believe that open collaboration +is key to the success of our project, and we are committed to creating an environment where everyone can contribute. + +## 3. Inclusivity and Diversity + +We value diversity and believe that it is essential to building a strong and vibrant community. We are committed to creating an inclusive +environment where everyone feels welcome and can participate, regardless of their race, gender, sexual orientation, religion, or any other +personal characteristic. + +## 4. Safety and Security + +We are committed to creating a safe and secure environment for all contributors. We will not tolerate harassment, discrimination, or any other +form of abusive behavior, and we will take appropriate action to address any such behavior. + +## 5. Accountability and Responsibility + +We hold ourselves and our community members accountable for upholding these values. We will take responsibility for our actions and strive to make +amends for any harm we may cause. We will also hold others accountable for their actions, and we will support those who are harmed by any unacceptable +behavior. + +## 6. Continuous Improvement + +We are committed to continuous improvement and will actively seek feedback from our community members. We will use this feedback to improve our +project and create a better environment for everyone. + +### Enforcement + +Any violations of this code of conduct may be reported to the project maintainers at hello@bitbag.io. All complaints will be reviewed and +investigated promptly and fairly. The project team reserves the right to remove, edit, or reject comments, commits, code, wiki edits, issues, and +other contributions that are not aligned with this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that +they deem inappropriate, threatening, offensive, or harmful. + +### Attribution + +This Code of Conduct is adapted from the Contributor Covenant (https://www.contributor-covenant.org/), version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +### Conclusion + +We believe that following these values will help us create a positive and inclusive community that welcomes and encourages contributions from everyone. +We thank all contributors for their support and commitment to these values. diff --git a/OpenMarketplace/CONTRIBUTING.md b/OpenMarketplace/CONTRIBUTING.md new file mode 100644 index 0000000..0b092ee --- /dev/null +++ b/OpenMarketplace/CONTRIBUTING.md @@ -0,0 +1,155 @@ + +# Contributing to Open Marketplace + +First off, thanks for taking the time to contribute! ❤️ + +All types of contributions are encouraged and valued. See the [Table of Contents](#table-of-contents) for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉 + +> And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about: +> - Star the project +> - Tweet about it +> - Refer this project in your project's readme +> - Mention the project at local meetups and tell your friends/colleagues + + +## Table of Contents + +- [I Have a Question](#i-have-a-question) +- [I Want To Contribute](#i-want-to-contribute) + - [Reporting Bugs](#reporting-bugs) + - [Suggesting Enhancements](#suggesting-enhancements) + - [Your First Code Contribution](#your-first-code-contribution) +- [Styleguide](#styleguide) +- [Communication](#communication) + + + +## I Have a Question + +> If you want to ask a question, we assume that you have read the available [Documentation](https://github.com/BitBagCommerce/OpenMarketplace/blob/master/README.md). + +Before you ask a question, it is best to search for existing [Issues](https://github.com/BitBagCommerce/OpenMarketplace/issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first. + +If you then still feel the need to ask a question and need clarification, we recommend the following: + +- Open an [Issue](https://github.com/BitBagCommerce/OpenMarketplace/issues/new). +- Provide as much context as you can about what you're running into. +- Provide project and platform versions (nodejs, npm, etc), depending on what seems relevant. + +We will then take care of the issue as soon as possible. + + + +## I Want To Contribute + +> ### Legal Notice +> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license. + +### Reporting Bugs + + +#### Before Submitting a Bug Report + +A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible. + +- Make sure that you are using the latest version. +- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](https://github.com/BitBagCommerce/OpenMarketplace/blob/master/README.md). If you are looking for support, you might want to check [this section](#i-have-a-question)). +- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/BitBagCommerce/OpenMarketplaceissues?q=label%3Abug). +- Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue. +- Collect information about the bug: + - Stack trace (Traceback) + - OS, Platform and Version (Windows, Linux, macOS, x86, ARM) + - Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant. + - Possibly your input and the output + - Can you reliably reproduce the issue? And can you also reproduce it with older versions? + + +#### How Do I Submit a Good Bug Report? + +> You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public. Instead sensitive bugs must be sent by email to <>. + + +We use GitHub issues to track bugs and errors. If you run into an issue with the project: + +- Open an [Issue](https://github.com/BitBagCommerce/OpenMarketplace/issues/new). (Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about a bug yet and not to label the issue.) +- Explain the behavior you would expect and the actual behavior. +- Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case. +- Provide the information you collected in the previous section. + +Once it's filed: + +- The project team will label the issue accordingly. +- A team member will try to reproduce the issue with your provided steps. If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for those steps and mark the issue as `needs-repro`. Bugs with the `needs-repro` tag will not be addressed until they are reproduced. +- If the team is able to reproduce the issue, it will be marked `needs-fix`, as well as possibly other tags (such as `critical`), and the issue will be left to be [implemented by someone](#your-first-code-contribution). + + + + +### Suggesting Enhancements + +This section guides you through submitting an enhancement suggestion for Open Marketplace, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions. + + +#### Before Submitting an Enhancement + +- Make sure that you are using the latest version. +- Read the [documentation](https://github.com/BitBagCommerce/OpenMarketplace/blob/master/README.md) carefully and find out if the functionality is already covered, maybe by an individual configuration. +- Perform a [search](https://github.com/BitBagCommerce/OpenMarketplace/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. +- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library. + + +#### How Do I Submit a Good Enhancement Suggestion? + +Enhancement suggestions are tracked as [GitHub issues](https://github.com/BitBagCommerce/OpenMarketplace/issues). + +- Use a **clear and descriptive title** for the issue to identify the suggestion. +- Provide a **step-by-step description of the suggested enhancement** in as many details as possible. +- **Describe the current behavior** and **explain which behavior you expected to see instead** and why. At this point you can also tell which alternatives do not work for you. +- You may want to **include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. +- **Explain why this enhancement would be useful** to most Open Marketplace users. You may also want to point out the other projects that solved it better and which could serve as inspiration. + + + +### Your First Code Contribution +Thank you for your interest in contributing! These guidelines will help you get started with making your first contribution. We value and appreciate your input, so thank you in advance for taking the time to contribute to our project. + +#### Getting Started + +To begin, please make sure you have reviewed all documents related to contributing and our code of conduct. + +Once you're ready to contribute, follow these steps: + +1. **Fork the repository:** Start by creating your own fork of the project repository. This will allow you to work on your changes without affecting the main project. +2. **Clone the repository:** Clone the forked repository to your local machine using `git clone https://github.com/your-username/repository.git`. +3. **Create a new branch:** Create a new branch for your contribution. This helps keep your changes organized and makes it easier to merge them later. You can create a branch using `git checkout -b branch-name`. +4. **Make your changes:** Now it's time to make your contribution! Whether it's fixing a bug, adding a new feature, or improving documentation, your contribution is valuable. Feel free to explore the codebase and make your changes accordingly. +5. **Test your changes:** Before submitting your contribution, make sure to test your changes locally to ensure they work as intended. This includes running any necessary tests and checking for any potential issues. +6. **Commit and push:** Once you're satisfied with your changes, commit them using `git commit -m "Your commit message"`. Then, push the changes to your forked repository with `git push origin branch-name`. +7. **Submit a pull request:** Finally, head over to the original repository on GitHub and submit a pull request. In your pull request, provide a clear and descriptive explanation of the changes you've made. This will help the project maintainers review and merge your contribution more efficiently. + +## Styleguide + +We adhere to a specific set of code style and guidelines to maintain consistency across the project. Please ensure that your contributions follow these guidelines to streamline the review process. You can find the guidelines in the [project's documentation](https://github.com/BitBagCommerce/OpenMarketplace/STYLEGUIDE.md). + +## Communication + +If you have any questions or need assistance while making your contribution, feel free to reach out to us. You can use GitHub issues, our Slack channel, or any other communication methods mentioned in the project documentation. We're here to help you have a smooth and successful experience contributing to our project. + +Once again, thank you for your interest in contributing to our project. We greatly appreciate your time and effort. Together, we can make the project even better! + +Happy contributing! + + diff --git a/OpenMarketplace/Dockerfile b/OpenMarketplace/Dockerfile new file mode 100644 index 0000000..0ab4b02 --- /dev/null +++ b/OpenMarketplace/Dockerfile @@ -0,0 +1,178 @@ +# the different stages of this Dockerfile are meant to be built into separate images +# https://docs.docker.com/compose/compose-file/#target + +ARG PHP_VERSION=8.1 +ARG NODE_VERSION=14.17.3 +ARG NGINX_VERSION=1.21 +ARG ALPINE_VERSION=3.15 +ARG NODE_ALPINE_VERSION=3.14 +ARG COMPOSER_VERSION=2.4 +ARG PHP_EXTENSION_INSTALLER_VERSION=latest + +FROM composer:${COMPOSER_VERSION} AS composer + +FROM mlocati/php-extension-installer:${PHP_EXTENSION_INSTALLER_VERSION} AS php_extension_installer + +FROM php:${PHP_VERSION}-fpm-alpine${ALPINE_VERSION} AS base + +# persistent / runtime deps +RUN apk add --no-cache \ + acl \ + file \ + gettext \ + unzip \ + ; + +COPY --from=php_extension_installer /usr/bin/install-php-extensions /usr/local/bin/ + +# default PHP image extensions +# ctype curl date dom fileinfo filter ftp hash iconv json libxml mbstring mysqlnd openssl pcre PDO pdo_sqlite Phar +# posix readline Reflection session SimpleXML sodium SPL sqlite3 standard tokenizer xml xmlreader xmlwriter zlib +RUN install-php-extensions apcu exif gd intl pdo_mysql opcache zip + +COPY --from=composer /usr/bin/composer /usr/bin/composer +COPY docker/php/prod/php.ini $PHP_INI_DIR/php.ini +COPY docker/php/prod/opcache.ini $PHP_INI_DIR/conf.d/opcache.ini + +# copy file required by opcache preloading +COPY config/preload.php /srv/open_marketplace/config/preload.php + +# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser +ENV COMPOSER_ALLOW_SUPERUSER=1 +RUN set -eux; \ + composer clear-cache +ENV PATH="${PATH}:/root/.composer/vendor/bin" + +WORKDIR /srv/open_marketplace + +# build for production +ENV APP_ENV=prod + +# prevent the reinstallation of vendors at every changes in the source code +COPY composer.* ./ +RUN set -eux; \ + composer install --prefer-dist --no-autoloader --no-interaction --no-scripts --no-progress --no-dev; \ + composer clear-cache + +# copy only specifically what we need +COPY .env .env.prod ./ +COPY assets assets/ +COPY bin bin/ +COPY config config/ +COPY public public/ +COPY src src/ +COPY templates templates/ +COPY translations translations/ + +RUN set -eux; \ + mkdir -p var/cache var/log; \ + composer dump-autoload --classmap-authoritative; \ + APP_SECRET='' composer run-script post-install-cmd; \ + chmod +x bin/console; sync; \ + bin/console sylius:install:assets --no-interaction; \ + bin/console sylius:theme:assets:install public --no-interaction + +VOLUME /srv/open_marketplace/var + +VOLUME /srv/open_marketplace/public/media + +COPY docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint +RUN chmod +x /usr/local/bin/docker-entrypoint + +ENTRYPOINT ["docker-entrypoint"] +CMD ["php-fpm"] + +FROM node:${NODE_VERSION}-alpine${NODE_ALPINE_VERSION} AS open_marketplace_node + +WORKDIR /srv/open_marketplace + +RUN set -eux; \ + apk add --no-cache --virtual .build-deps \ + g++ \ + gcc \ + make \ + ; + +# prevent the reinstallation of vendors at every changes in the source code +COPY package.json yarn.* ./ +RUN set -eux; \ + yarn install; \ + yarn cache clean + +COPY --from=base /srv/open_marketplace/vendor/sylius/sylius/src/Sylius/Bundle/UiBundle/Resources/private vendor/sylius/sylius/src/Sylius/Bundle/UiBundle/Resources/private/ +COPY --from=base /srv/open_marketplace/vendor/sylius/sylius/src/Sylius/Bundle/AdminBundle/Resources/private vendor/sylius/sylius/src/Sylius/Bundle/AdminBundle/Resources/private/ +COPY --from=base /srv/open_marketplace/vendor/sylius/sylius/src/Sylius/Bundle/ShopBundle/Resources/private vendor/sylius/sylius/src/Sylius/Bundle/ShopBundle/Resources/private/ +COPY --from=base /srv/open_marketplace/assets ./assets +COPY --from=base /srv/open_marketplace/vendor/bitbag/wishlist-plugin/webpack.config.js vendor/bitbag/wishlist-plugin/webpack.config.js +COPY --from=base /srv/open_marketplace/vendor/bitbag/cms-plugin/webpack.config.js vendor/bitbag/cms-plugin/webpack.config.js +COPY --from=base /srv/open_marketplace/vendor/bitbag/wishlist-plugin/src/Resources/assets vendor/bitbag/wishlist-plugin/src/Resources/assets +COPY --from=base /srv/open_marketplace/vendor/bitbag/cms-plugin/src/Resources/assets vendor/bitbag/cms-plugin/src/Resources/assets + +COPY webpack.config.js ./ +RUN yarn prod + +COPY docker/node/docker-entrypoint.sh /usr/local/bin/docker-entrypoint +RUN chmod +x /usr/local/bin/docker-entrypoint + +ENTRYPOINT ["docker-entrypoint"] +CMD ["yarn", "prod"] + +FROM base AS open_marketplace_php_prod + +COPY --from=open_marketplace_node /srv/open_marketplace/public/build public/build + +FROM nginx:${NGINX_VERSION}-alpine AS open_marketplace_nginx + +COPY docker/nginx/conf.d/default.conf /etc/nginx/conf.d/ + +WORKDIR /srv/open_marketplace + +COPY --from=base /srv/open_marketplace/public public/ +COPY --from=open_marketplace_node /srv/open_marketplace/public public/ + +FROM open_marketplace_php_prod AS open_marketplace_php_dev + +COPY docker/php/dev/php.ini $PHP_INI_DIR/php.ini +COPY docker/php/dev/opcache.ini $PHP_INI_DIR/conf.d/opcache.ini + +WORKDIR /srv/open_marketplace + +ENV APP_ENV=dev + +COPY .env.test ./ + +RUN set -eux; \ + composer install --prefer-dist --no-autoloader --no-interaction --no-scripts --no-progress; \ + composer clear-cache + +FROM open_marketplace_php_prod AS open_marketplace_cron + +RUN set -eux; \ + apk add --no-cache --virtual .build-deps \ + apk-cron \ + ; + +COPY docker/cron/crontab /etc/crontabs/root +COPY docker/cron/docker-entrypoint.sh /usr/local/bin/docker-entrypoint +RUN chmod +x /usr/local/bin/docker-entrypoint + +ENTRYPOINT ["docker-entrypoint"] +CMD ["crond", "-f"] + +FROM open_marketplace_php_prod AS open_marketplace_migrations_prod + +RUN apk add --no-cache wget +COPY docker/migrations/docker-entrypoint.sh /usr/local/bin/docker-entrypoint +RUN chmod +x /usr/local/bin/docker-entrypoint + +ENTRYPOINT ["docker-entrypoint"] + +FROM open_marketplace_php_dev AS open_marketplace_migrations_dev + +RUN apk add --no-cache wget +COPY docker/migrations/docker-entrypoint.sh /usr/local/bin/docker-entrypoint +RUN chmod +x /usr/local/bin/docker-entrypoint + +RUN composer dump-autoload --classmap-authoritative + +ENTRYPOINT ["docker-entrypoint"] diff --git a/OpenMarketplace/README.md b/OpenMarketplace/README.md new file mode 100644 index 0000000..c448490 --- /dev/null +++ b/OpenMarketplace/README.md @@ -0,0 +1,92 @@ +

+ + + +

+ +

+ + Build + + + Chat + + + Contact + +

+ +Official website: http://open-marketplace.io
+Demo: http://demo.open-marketplace.io + +BitBag OpenMarketplace is the first open-source marketplace platform. The solution is based on Sylius, Symfony and Semantic UI meaning it is fully compatible with each. The platform is highly customizable project made using full-stack BDD with Behat and PHPSpec. + +Like what we do? Give us a star! ⭐ + +Looking for a professional team to build a MVM for your business on top of open-source? [Contact us!](https://bitbag.io/contact-us) + +--- +

+ + + +

+ +# Table of Contents + +* [Overview](#overview) +* [Customization](#customization) +* [Contribution](#contribution) +* [Support](#we-are-here-to-help) +* [About us](#about-bitbag) +* [License](#license) +* [Authors](#Authors) +* [Contact](#contact) + +# Overview + +- [Installation](./doc/installation.md) +- [Vendor profile](./doc/vendor-profile.md) +- [Conversations](./doc/conversations.md) +- [Product Listing](./doc/product_listings.md) +- [Shipment](./doc/manage_shipping_methods.md) +- [Order Process](./doc/order_process.md) +- [Order management](./doc/manage_orders.md) +- [Clients](./doc/manage_clients.md) +- [Product Reviews](./doc/manage_product_reviews.md) +- [Customization](./doc/how_to_customize.md) +- [API](./doc/api.md) + +## Customization + +Our project is highly customizable, [here](./doc/how_to_customize.md) is our guide on how to do it. + +## Contribution + +Every contribution is meaningful, kudos to everyone who helped us with developing this project! Issues and PRs are welcomed. + +## We are here to help + +This **open-source project was developed to help the Sylius community**. If you have any additional questions, would like help with installing or configuring the plugin, or need any assistance with your Sylius project - let us know! For community support, join the official [OpenMarketplace Community Slack](https://join.slack.com/t/openmarketplacegroup/shared_invite/zt-1vejiwrbn-XZkLwRH5L0s4L9~qfkcP~g). + +If you want to participate in the development, you can do it by submitting [pull requests](https://github.com/BitBagCommerce/OpenMarketplace/pulls) or reporting [issues](https://github.com/BitBagCommerce/OpenMarketplace/issues). + +## About BitBag + +BitBag is a Software House working on digital commerce projects on top of best open-source technologies, such as Sylius, Shopware, Pimcore, Symfony and Vue Storefront. We work with worldwide companies who see eCommerce as an important factor of their strategy. + +If you think we could help your business within the above-mentioned technology stack, contact us directly. We could be the right people to do the job. Fill the form on [this site](https://bitbag.io/contact-us/) or send us an e-mail at hello@bitbag.io. + +## License + +This project's source code is completely free and released under the terms of the MIT license. + +## Authors + +See the full list of contributors [here](https://github.com/BitBagCommerce/OpenMarketplace/contributors). + +## Contact + +You can contact us using the contact form on [our website](https://bitbag.io/contact-us/) or send us an e-mail to hello@bitbag.io with your question(s). We are also active on the [community Slack](https://join.slack.com/t/openmarketplacegroup/shared_invite/zt-1ij1t41wx-HfAR6~URm3OAcqm0jc423Q). + +[![](https://bitbag.io/wp-content/uploads/2021/08/badges-bitbag.png)](https://bitbag.io/contact-us/) diff --git a/OpenMarketplace/STYLEGUIDE.md b/OpenMarketplace/STYLEGUIDE.md new file mode 100644 index 0000000..8bcffea --- /dev/null +++ b/OpenMarketplace/STYLEGUIDE.md @@ -0,0 +1,77 @@ +# OpenMarketplace - Style Guide + +## Introduction + +Thank you for taking the time to contribute to this project! We appreciate everyone who puts in the effort to better this project. + +This style guide serves as a reference for developers contributing to the OpenMarketplace project. Consistent coding styles and guidelines are essential for +maintainability and readability of the codebase. Please adhere to the guidelines outlined in this document when making contributions. + +## Table of Contents + +- [General Guidelines](#general-guidelines) +- [Naming Conventions](#naming-conventions) +- [Code Formatting](#code-formatting) +- [Documentation](#documentation) +- [Testing](#testing) +- [Version Control](#version-control) +- [Dependencies](#dependencies) + +## General Guidelines + +- Write clean, readable, and maintainable code. +- Follow the principle of DRY (Don't Repeat Yourself). +- Aim for code simplicity and avoid unnecessary complexity. +- Strive for consistent and meaningful variable and function names. +- Keep lines of code within a reasonable length (80-120 characters). +- Use comments to explain complex logic or non-obvious code sections. + +## Naming Conventions + +- Use descriptive and meaningful names for variables, functions, classes, and files. +- Follow the standard naming conventions for the programming language used in the project. +- Prefer clarity over brevity in naming. Avoid overly abbreviated or cryptic names. +- Follow [PSR-12 rules](https://www.php-fig.org/psr/psr-12/) when contributing the project. + +## Code Formatting + +- Use consistent indentation (spaces or tabs) throughout the codebase. +- Configure your code editor to use a standardized indentation size (e.g., 4 spaces). +- Use a consistent line-ending style (e.g., Unix style: LF). +- Remove trailing whitespace at the end of lines. +- Maintain a consistent code style within each file and across the entire codebase. + +## Documentation + +- Document code to provide clarity and understanding. +- Use clear and concise comments to explain the purpose and functionality of code blocks. + +## Testing + +- Write unit tests for all significant functionality. +- Ensure that the tests cover a wide range of input cases, including edge cases and error conditions. +- Follow the project's established testing framework and conventions. +- Maintain a high test coverage to ensure code stability and reliability. + +## Version Control + +- Follow Git best practices, such as using descriptive commit messages, creating meaningful branch names, and regularly pulling changes from the main branch. +- Avoid committing large binary files or sensitive information to the repository. +- Use proper branching strategies, such as feature branches or Git flow, to organize and manage development. + +## Dependencies + +- Clearly define and document project dependencies, including libraries, frameworks, and external tools. +- Specify dependency versions to ensure consistent behavior across different environments. +- Regularly update and review dependencies to ensure security and compatibility. + +## Conclusion + +Adhering to this style guide will ensure a consistent and well-maintained codebase for the OpenMarketplace project. Consistency in coding styles, naming conventions, +code formatting, documentation, testing, version control, and dependency management will contribute to better collaboration among developers and make the project more +maintainable and readable. + +Remember to review and update this style guide periodically as the project evolves. By following these guidelines, we can create high-quality code and foster a positive +development environment. + +Thank you for your contributions to the OpenMarketplace project! diff --git a/OpenMarketplace/UPGRADE.md b/OpenMarketplace/UPGRADE.md new file mode 100644 index 0000000..8c28fba --- /dev/null +++ b/OpenMarketplace/UPGRADE.md @@ -0,0 +1,122 @@ +# UPGRADE FROM `v1.3.X` TO `v1.4.0` + +First step is upgrading Sylius with composer + +- `composer require sylius/sylius:~1.4.0` + +### Test application database + +#### Migrations + +If you provide migrations with your plugin, take a look at following changes: + +* Change base `AbstractMigration` namespace to `Doctrine\Migrations\AbstractMigration` +* Add `: void` return types to both `up` and `down` functions + +#### Schema update + +If you don't use migrations, just run `(cd tests/Application && bin/console doctrine:schema:update --force)` to update the test application's database schema. + +### Dotenv + +* `composer require symfony/dotenv:^4.2 --dev` +* Follow [Symfony dotenv update guide](https://symfony.com/doc/current/configuration/dot-env-changes.html) to incorporate required changes in `.env` files structure. Remember - they should be done on `tests/Application/` level! Optionally, you can take a look at [corresponding PR](https://github.com/Sylius/PluginSkeleton/pull/156/) introducing these changes in **PluginSkeleton** (this PR also includes changes with Behat - see below) + +Don't forget to clear the cache (`tests/Application/bin/console cache:clear`) to be 100% everything is loaded properly. + +### Test application kernel + +The kernel of the test application needs to be replaced with this [file](https://github.com/Sylius/PluginSkeleton/blob/1.4/tests/Application/Kernel.php). +The location of the kernel is: `tests/Application/Kernel.php` (replace the content with the content of the file above). +The container cleanup method is removed in the new version and keeping it will cause problems with for example the `TagAwareAdapter` which will call `commit()` on its pool from its destructor. If its pool is `TraceableAdapter` with pool `ArrayAdapter`, then the pool property of `TraceableAdapter` will be nullified before the destructor is executed and cause an error. + +--- + +### Behat + +If you're using Behat and want to be up-to-date with our configuration + +* Update required extensions with `composer require friends-of-behat/symfony-extension:^2.0 friends-of-behat/page-object-extension:^0.3 --dev` +* Remove extensions that are not needed yet with `composer remove friends-of-behat/context-service-extension friends-of-behat/cross-container-extension friends-of-behat/service-container-extension --dev` +* Update your `behat.yml` - look at the diff [here](https://github.com/Sylius/Sylius-Standard/pull/322/files#diff-7bde54db60a6e933518d8b61b929edce) +* Add `SymfonyExtensionBundle` to your `tests/Application/config/bundles.php`: + ```php + return [ + //... + FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle::class => ['test' => true, 'test_cached' => true], + ]; + ``` +* If you use our Travis CI configuration, follow [these changes](https://github.com/Sylius/PluginSkeleton/pull/156/files#diff-354f30a63fb0907d4ad57269548329e3) introduced in `.travis.yml` file +* Create `tests/Application/config/services_test.yaml` file with the following code and add these your own Behat services as well: + ```yaml + imports: + - { resource: "../../../vendor/sylius/sylius/src/Sylius/Behat/Resources/config/services.xml" } + ``` +* Remove all `__symfony__` prefixes in your Behat services +* Remove all `` tags from your Behat services +* Make your Behat services public by default with `` +* Change `contexts_services ` in your suite definitions to `contexts` +* Take a look at [SymfonyExtension UPGRADE guide](https://github.com/FriendsOfBehat/SymfonyExtension/blob/master/UPGRADE-2.0.md) if you have any more problems + +### Phpstan + +* Fix the container XML path parameter in the `phpstan.neon` file as done [here](https://github.com/Sylius/PluginSkeleton/commit/37fa614dbbcf8eb31b89eaf202b4bd4d89a5c7b3) + +# UPGRADE FROM `v1.2.X` TO `v1.4.0` + +Firstly, check out the [PluginSkeleton 1.3 upgrade guide](https://github.com/Sylius/PluginSkeleton/blob/1.4/UPGRADE-1.3.md) to update Sylius version step by step. +To upgrade to Sylius 1.4 follow instructions from [the previous section](https://github.com/Sylius/PluginSkeleton/blob/1.4/UPGRADE-1.4.md#upgrade-from-v13x-to-v140) with following changes: + +### Doctrine migrations + +* Change namespaces of copied migrations to `Sylius\Migrations` + +### Dotenv + +* These changes are not required, but can be done as well, if you've changed application directory structure in `1.2.x` to `1.3` update + +### Behat + +* Add `\FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle()` to your bundles lists in `tests/Application/AppKernel.php` (preferably only in `test` environment) +* Import Sylius Behat services in `tests/Application/config/config_test.yml` and your own Behat services as well: + ```yaml + imports: + - { resource: "../../../../vendor/sylius/sylius/src/Sylius/Behat/Resources/config/services.xml" } + ``` +* Specify test application's kernel path in `behat.yml`: + ```yaml + FriendsOfBehat\SymfonyExtension: + kernel: + class: AppKernel + path: tests/Application/app/AppKernel.php + ``` + + +# UPGRADE FROM `v1.2.X` TO `v1.3.0` + +## Application + +* Run `composer require sylius/sylius:~1.3.0 --no-update` + +* Add the following code in your `behat.yml(.dist)` file: + + ```yaml + default: + extensions: + FriendsOfBehat\SymfonyExtension: + env_file: ~ + ``` + +* Incorporate changes from the following files into plugin's test application: + + * [`tests/Application/package.json`](https://github.com/Sylius/PluginSkeleton/blob/1.3/tests/Application/package.json) ([see diff](https://github.com/Sylius/PluginSkeleton/pull/134/files#diff-726e1353c14df7d91379c0dea6b30eef)) + * [`tests/Application/.babelrc`](https://github.com/Sylius/PluginSkeleton/blob/1.3/tests/Application/.babelrc) ([see diff](https://github.com/Sylius/PluginSkeleton/pull/134/files#diff-a2527d9d8ad55460b2272274762c9386)) + * [`tests/Application/.eslintrc.js`](https://github.com/Sylius/PluginSkeleton/blob/1.3/tests/Application/.eslintrc.js) ([see diff](https://github.com/Sylius/PluginSkeleton/pull/134/files#diff-396c8c412b119deaa7dd84ae28ae04ca)) + +* Update PHP and JS dependencies by running `composer update` and `(cd tests/Application && yarn upgrade)` + +* Clear cache by running `(cd tests/Application && bin/console cache:clear)` + +* Install assets by `(cd tests/Application && bin/console assets:install web)` and `(cd tests/Application && yarn build)` + +* optionally, remove the build for PHP 7.1. in `.travis.yml` diff --git a/OpenMarketplace/assets/admin/entry.js b/OpenMarketplace/assets/admin/entry.js new file mode 100644 index 0000000..c3059db --- /dev/null +++ b/OpenMarketplace/assets/admin/entry.js @@ -0,0 +1,5 @@ +import 'sylius/bundle/AdminBundle/Resources/private/entry'; + +import './scss/main.scss' + +import './js' diff --git a/OpenMarketplace/assets/admin/js/index.js b/OpenMarketplace/assets/admin/js/index.js new file mode 100644 index 0000000..e69de29 diff --git a/OpenMarketplace/assets/admin/scss/main.scss b/OpenMarketplace/assets/admin/scss/main.scss new file mode 100644 index 0000000..99761a3 --- /dev/null +++ b/OpenMarketplace/assets/admin/scss/main.scss @@ -0,0 +1,61 @@ +$base-box-shadow: 1px 1px 16px rgba(0, 0, 0, 0.04); +$base-border-radius: 8px; +$base-color: #339ae8; +.toolbar-brand { + background-color: #000; + border-radius: 8px; + color: #fff; + padding:10px; + margin-top: 10px; + margin-bottom: 10px; +} +.toolbar-brand:hover { + background-color: #454545; + color: #fff; +} +.stats .ui.basic.active.button { + color: $base-color !important; +} +a { + color: #339ae8; +} +.ui.primary.button { + background-color: $base-color; +} +#sidebar.ui.sidebar.vertical.menu .item.active { + font-weight: inherit !important; + background: $base-color !important; + border-radius: 0px 99px 99px 0px !important; +} +.ui.primary.button:hover, .ui.primary.button:focus { + background-color: #42a3ee; +} +.sylius-grid-table-wrapper .ui.sortable.table thead th.sorted { + color: $base-color; +} +.ui.styled.accordion { + box-shadow: $base-box-shadow; + border-radius: $base-border-radius; +} +.ui.segment, .ui.attached.segment { + box-shadow: $base-box-shadow; + border-radius: $base-border-radius; +} +.ui.form .field > input:focus, .ui.form .field > textarea:focus { + border-color: rgba(66, 154, 232, 0.4); +} +.ui.toggle.checkbox input:checked ~ .box:before, .ui.toggle.checkbox input:checked ~ label:before, .ui.toggle.checkbox input:focus:checked ~ .box:before, .ui.toggle.checkbox input:focus:checked ~ label:before { + background-color: $base-color !important; +} +.ui.teal.labels .label, .ui.teal.label { + background-color: $base-color !important; + border-color: $base-color !important; + color: #FFFFFF !important; +} +.ui.header .circular.icon { + color: $base-color; + background: rgba(51, 154, 232, 0.1); +} +.ui.button.teal { + background-color: $base-color !important; +} diff --git a/OpenMarketplace/assets/shop/entry.js b/OpenMarketplace/assets/shop/entry.js new file mode 100644 index 0000000..964f6c6 --- /dev/null +++ b/OpenMarketplace/assets/shop/entry.js @@ -0,0 +1,5 @@ +import 'sylius/bundle/ShopBundle/Resources/private/entry'; + +import './scss/main.scss' + +import './js' diff --git a/OpenMarketplace/assets/shop/js/index.js b/OpenMarketplace/assets/shop/js/index.js new file mode 100644 index 0000000..e69de29 diff --git a/OpenMarketplace/assets/shop/scss/Vendor/product_listing/_product_listing_dropdown.scss b/OpenMarketplace/assets/shop/scss/Vendor/product_listing/_product_listing_dropdown.scss new file mode 100644 index 0000000..ce2e001 --- /dev/null +++ b/OpenMarketplace/assets/shop/scss/Vendor/product_listing/_product_listing_dropdown.scss @@ -0,0 +1,31 @@ +.send-for-verification { + background: white; + border: none; + padding: 0.7857142rem 1.14285714rem !important; + width: 100%; + text-align: left; +} + +.send-for-verification:hover { + background: rgba(34,36,38,.1); +} + +.send-for-verification i{ + margin-right: 0.78rem; +} + +.require_confirmation_button { + background: white; + border: none; + padding: 0.7857142rem 1.14285714rem !important; + width: 100%; + text-align: left; +} + +.require_confirmation_button:hover { + background: rgba(34,36,38,.1); +} + +.MVM_Button i{ + margin-right: 0.78rem; +} diff --git a/OpenMarketplace/assets/shop/scss/Vendor/product_review/_dropdown.scss b/OpenMarketplace/assets/shop/scss/Vendor/product_review/_dropdown.scss new file mode 100644 index 0000000..1a39e3c --- /dev/null +++ b/OpenMarketplace/assets/shop/scss/Vendor/product_review/_dropdown.scss @@ -0,0 +1,15 @@ +.product-review-dropdown { + button { + &.item { + background: white; + border: none; + padding: 0.7857142rem 1.14285714rem !important; + width: 100%; + text-align: left; + + &:hover { + background: rgba(34,36,38,.1); + } + } + } +} diff --git a/OpenMarketplace/assets/shop/scss/address_book/_address_book.scss b/OpenMarketplace/assets/shop/scss/address_book/_address_book.scss new file mode 100644 index 0000000..35a7380 --- /dev/null +++ b/OpenMarketplace/assets/shop/scss/address_book/_address_book.scss @@ -0,0 +1,12 @@ +@media (max-width: 767px) { + #sylius-addresses, #sylius-default-address { + .ui.vertical.buttons { + flex-direction: row; + } + .ui.vertical .button.icon.labeled.ui { + height: 100%; + display: flex; + align-items: center; + } + } +} \ No newline at end of file diff --git a/OpenMarketplace/assets/shop/scss/attributes/_attributes.scss b/OpenMarketplace/assets/shop/scss/attributes/_attributes.scss new file mode 100644 index 0000000..3223f83 --- /dev/null +++ b/OpenMarketplace/assets/shop/scss/attributes/_attributes.scss @@ -0,0 +1,99 @@ +.attributes-group { + border: 1px solid rgba(34, 36, 38, 0.1); + + &:not(:last-child) { + border-bottom: 0; + } + + &:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; + } + + &:last-child { + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + } +} + +.attributes-header { + display: flex; + align-items: center; + justify-content: space-between; + background: rgba(0, 0, 0, 0.03); + padding: 0.5em 1.8em; + border-bottom: 1px solid rgba(34, 36, 38, 0.1); + + .ui.basic.red.button { + box-shadow: none !important; + + &:hover { + background: rgba(255, 0, 0, 0.1) !important; + } + } +} + +.attributes-list { + padding: 1.4em 1.8em; +} + +.attribute-row { + flex-wrap: wrap; + margin: 10px 0; + + @media (min-width: 1152px) { + display: flex; + } +} + +.attribute-label { + align-self: center; + width: 200px; + margin-right: 20px; + padding-top: 5px; + padding-bottom: 5px; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + + i { + width: 20px; + text-align: left; + } +} + +.attribute-input { + flex-grow: 1; +} + +.attribute-input, .attribute-input div:not(.checkbox) { + display: flex; + flex-grow: 1; + align-items: center; +} + +.attribute-input *:not(:last-child) { + margin-right: 5px; +} + +.attribute-input *:not(:first-child) { + margin-left: 5px; +} + +.attribute-input textarea { + height: 6em !important; + min-height: 6em !important; +} + +.attribute-action > * { + margin: 4px 0 !important; + + @media (min-width: 1152px) { + margin: 0 0 0 10px !important; + } +} + +.attribute-error { + width: 100%; + text-align: center; +} diff --git a/OpenMarketplace/assets/shop/scss/error_pages/_error_pages.scss b/OpenMarketplace/assets/shop/scss/error_pages/_error_pages.scss new file mode 100644 index 0000000..f44036b --- /dev/null +++ b/OpenMarketplace/assets/shop/scss/error_pages/_error_pages.scss @@ -0,0 +1,15 @@ +.ui.stripe.segment.error-container { + padding: 5em 0; + + a.button { + margin-top: 12px; + } +} + +.error-section { + margin: 3em 0; +} + +.ui.error-page.image { + display: inline-block; +} diff --git a/OpenMarketplace/assets/shop/scss/main.scss b/OpenMarketplace/assets/shop/scss/main.scss new file mode 100644 index 0000000..bb7771b --- /dev/null +++ b/OpenMarketplace/assets/shop/scss/main.scss @@ -0,0 +1,56 @@ +@import "./attributes/attributes"; +@import "Vendor/product_listing/product_listing_dropdown"; +@import "Vendor/product_review/dropdown"; +@import "./wishlist_button/index"; +@import "./vendor_page/vendor_banner"; +@import "./address_book/address_book"; +@import "./menu/horizontal_menu"; +@import "./error_pages/error_pages"; + +$base-box-shadow: 1px 1px 16px rgba(0, 0, 0, 0.04); +$base-border: 1px solid rgba(34, 36, 38, 0.1); +$base-border-radius: 8px; +$base-color: #339ae8; +body.pushable .pusher { + background-color: #fbfbfb; +} +.ui.cards > .card, .ui.card, .ui.segment, .ui.vertical.menu { + box-shadow: $base-box-shadow ; + border-radius: $base-border-radius; +} + +.ui.segment { + border: 1px solid rgba(123,126,130, 0.15); +} + +.ui.label.teal { + background-color: #0ab727 !important; +} + +.ui.label.blue { + background-color: #28afff !important; +} + +@media (max-width: 767px) { + .ui.table:not(.unstackable) { + thead { + display: table-header-group; + } + + tbody { + display: table-row-group!important; + } + + tr { + display: table-row!important; + } + + tr > td, tr > th { + display: table-cell!important; + } + + tr > td:not(:first-of-type), tr > th:not(:first-of-type) { + border-left: $base-border!important; + } + } +} diff --git a/OpenMarketplace/assets/shop/scss/menu/horizontal_menu.scss b/OpenMarketplace/assets/shop/scss/menu/horizontal_menu.scss new file mode 100644 index 0000000..d967b8a --- /dev/null +++ b/OpenMarketplace/assets/shop/scss/menu/horizontal_menu.scss @@ -0,0 +1,5 @@ +.bb-flex-taxon-menu{ + display: flex; + flex-wrap: wrap; + justify-content: center; +} diff --git a/OpenMarketplace/assets/shop/scss/vendor_page/_vendor_banner.scss b/OpenMarketplace/assets/shop/scss/vendor_page/_vendor_banner.scss new file mode 100644 index 0000000..041e64e --- /dev/null +++ b/OpenMarketplace/assets/shop/scss/vendor_page/_vendor_banner.scss @@ -0,0 +1,95 @@ +.vendor-banner{ + width: 100%; + min-width: 230px; + float: left; + position: relative; + min-height: 1px; + padding-left: 15px; + padding-right: 15px; + text-align: center; +} +.vendor-banner img { + width: 100%; + max-height: 240px; + object-fit: cover; +} +.img-container { + display: inline-block; + position: relative; + width: 100%; +} +.vendor-positioning{ + max-height: 80%; + position: absolute; + top: 0; + left: 0; + margin-top: 4rem; + margin-left: 2.5rem; + background-color: white; + color: black; + padding: 4px; + padding-right: 28px; + font-size: 17px; + line-height: 18px; + border: 1px solid #E0E0E0; +} + +.vendor-content { + display: flex; + align-items: center; + justify-content: center; + margin: 1rem +} +.vendor-content h2 { + margin-top: 0; +} + +.vendor-positioning p { + margin-bottom: 1rem; +} + +.vendor-logo { + display: flex; + align-items: center; + justify-content: center; + width: 3rem; + margin: 1%; +} + +.vendor-logo img { + width: 100%; + height: 100%; + margin-right: 0.5rem; +} + +@media (max-width: 767px) { + .img-container { + display: inline-block; + position: relative; + } + .vendor-positioning { + width: 100%; + max-height: 60%; + max-width: 100%; + position: relative; + font-size: 17px; + left: 0; + bottom: 0; + padding: 0; + line-height: 0; + } +} + +.reviews-count { + display: flex; + align-content: center; + align-items: baseline; + justify-content: flex-start; + margin-left: 14px; +} + +.reviews-count p { + margin-left: 0.5rem; + font-size: 1.25rem; + color: grey; +} diff --git a/OpenMarketplace/assets/shop/scss/wishlist_button/index.scss b/OpenMarketplace/assets/shop/scss/wishlist_button/index.scss new file mode 100644 index 0000000..367e6e5 --- /dev/null +++ b/OpenMarketplace/assets/shop/scss/wishlist_button/index.scss @@ -0,0 +1,46 @@ +$breakpoint-sm: 576px !default; + +.bb-wishlist-button > span > .icon{ + @media screen and (min-width: $breakpoint-sm) { + position: absolute; + left: 0; + top: 0; + height: 100%; + text-align: center; + width: 2.57142857em; + background-color: rgba(0, 0, 0, 0.05); + } +} + +.bb-wishlist-button > span > i.icon.heart:before{ + @media screen and (min-width: $breakpoint-sm) { + position: absolute; + display: block; + width: 100%; + top: 50%; + text-align: center; + transform: translateY(-50%); + } +} + +.bb-wishlist-button.ui.labeled.icon.button{ + @media screen and (max-width: $breakpoint-sm) { + display: flex !important; + justify-content: center; + padding-left: unset !important; + padding-right: unset !important; + width: 20%; + } +} + +.bb-wishlist-button > span > i.heart{ + @media screen and (max-width: $breakpoint-sm) { + margin: unset !important; + } +} + +.bb-wishlist-button > span.text{ + @media screen and (max-width: $breakpoint-sm) { + display: none !important; + } +} diff --git a/OpenMarketplace/behat.yml.dist b/OpenMarketplace/behat.yml.dist new file mode 100644 index 0000000..fc6fb2b --- /dev/null +++ b/OpenMarketplace/behat.yml.dist @@ -0,0 +1,42 @@ +imports: + - tests/Behat/Resources/suites.yml + +default: + extensions: + DMore\ChromeExtension\Behat\ServiceContainer\ChromeExtension: ~ + + FriendsOfBehat\MinkDebugExtension: + directory: etc/build + clean_start: false + screenshot: true + + Behat\MinkExtension: + files_path: "%paths.base%/tests/Behat/Resources/fixtures/" + base_url: "https://127.0.0.1:8080/" + default_session: symfony + javascript_session: chrome + sessions: + symfony: + symfony: ~ + chrome_headless: + chrome: + api_url: http://127.0.0.1:9222 + validate_certificate: false + chrome: + selenium2: + browser: chrome + firefox: + selenium2: + browser: firefox + show_auto: false + + FriendsOfBehat\SymfonyExtension: + bootstrap: config/bootstrap.php + kernel: + class: App\Kernel + + FriendsOfBehat\VariadicExtension: ~ + + FriendsOfBehat\SuiteSettingsExtension: + paths: + - "features" diff --git a/OpenMarketplace/bin/checks b/OpenMarketplace/bin/checks new file mode 100755 index 0000000..8d78f03 --- /dev/null +++ b/OpenMarketplace/bin/checks @@ -0,0 +1,55 @@ +#!/bin/bash + +clear +rm -Rf var/cache/* +APP_ENV=${APP_ENV} APP_DEBUG=${APP_DEBUG} bin/console cache:clear +if [[ $? -ne 0 ]]; +then + exit $?; +fi + +APP_ENV=${APP_ENV} APP_DEBUG=${APP_DEBUG} bin/console doctrine:database:create --if-not-exists +APP_ENV=${APP_ENV} APP_DEBUG=${APP_DEBUG} bin/console doctrine:schema:update --force --dump-sql +if [[ $? -ne 0 ]]; +then + exit $?; +fi + +APP_ENV=${APP_ENV} APP_DEBUG=${APP_DEBUG} bin/console doctrine:schema:validate +if [[ $? -ne 0 ]]; +then + exit $?; +fi + +vendor/bin/ecs check spec src tests +if [[ $? -ne 0 ]]; +then + exit $?; +fi + +vendor/bin/phpstan analyse -c phpstan.neon -l 8 src/ +if [[ $? -ne 0 ]]; +then + exit $?; +fi + +vendor/bin/phpspec run +if [[ $? -ne 0 ]]; +then + exit $?; +fi + +bin/console doctrine:schema:update --force --dump-sql --env=test +if [[ $? -ne 0 ]]; +then + exit $?; +fi + +vendor/bin/phpunit --colors=always +if [[ $? -ne 0 ]]; +then + exit $?; +fi + +vendor/bin/behat +exit $?; diff --git a/OpenMarketplace/bin/console b/OpenMarketplace/bin/console new file mode 100755 index 0000000..52fd398 --- /dev/null +++ b/OpenMarketplace/bin/console @@ -0,0 +1,38 @@ +#!/usr/bin/env php +getParameterOption(['--env', '-e'], null, true)) { + putenv('APP_ENV='.$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $env); +} + +if ($input->hasParameterOption('--no-debug', true)) { + putenv('APP_DEBUG='.$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0'); +} + +require dirname(__DIR__).'/config/bootstrap.php'; + +if ($_SERVER['APP_DEBUG']) { + umask(0000); + + if (class_exists(Debug::class)) { + Debug::enable(); + } +} + +$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']); +$application = new Application($kernel); +$application->run($input); diff --git a/OpenMarketplace/bin/create_node_symlink.php b/OpenMarketplace/bin/create_node_symlink.php new file mode 100644 index 0000000..10d69b4 --- /dev/null +++ b/OpenMarketplace/bin/create_node_symlink.php @@ -0,0 +1,45 @@ + `' . NODE_MODULES_FOLDER_NAME . '` already exists as a link or folder, keeping existing as may be intentional.' . PHP_EOL; + exit(0); + } else { + echo '> Invalid symlink `' . NODE_MODULES_FOLDER_NAME . '` detected, recreating...' . PHP_EOL; + if (!@unlink(NODE_MODULES_FOLDER_NAME)) { + echo '> Could not delete file `' . NODE_MODULES_FOLDER_NAME . '`.' . PHP_EOL; + exit(1); + } + } +} + +/* try to create the symlink using PHP internals... */ +$success = @symlink(PATH_TO_NODE_MODULES, NODE_MODULES_FOLDER_NAME); + +/* if case it has failed, but OS is Windows... */ +if (!$success && strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { + /* ...then try a different approach which does not require elevated permissions and folder to exist */ + echo '> This system is running Windows, creation of links requires elevated privileges,' . PHP_EOL; + echo '> and target path to exist. Fallback to NTFS Junction:' . PHP_EOL; + exec(sprintf('mklink /J %s %s 2> NUL', NODE_MODULES_FOLDER_NAME, PATH_TO_NODE_MODULES), $output, $returnCode); + $success = $returnCode === 0; + if (!$success) { + echo '> Failed o create the required symlink' . PHP_EOL; + exit(2); + } +} + +$path = @readlink(NODE_MODULES_FOLDER_NAME); +/* check if link points to the intended directory */ +if ($path && realpath($path) === realpath(PATH_TO_NODE_MODULES)) { + echo '> Successfully created the symlink.' . PHP_EOL; + exit(0); +} + +echo '> Failed to create the symlink to `' . NODE_MODULES_FOLDER_NAME . '`.' . PHP_EOL; +exit(3); diff --git a/OpenMarketplace/bin/fixtures b/OpenMarketplace/bin/fixtures new file mode 100755 index 0000000..58ac20d --- /dev/null +++ b/OpenMarketplace/bin/fixtures @@ -0,0 +1,20 @@ +#!/bin/bash + +BLUE='\033[1;33m' +NO_COLOR='\033[0m' # No Color +FILE=var/fixtures/images.zip +if [ ! -f "$FILE" ]; then + printf "\n${BLUE}Fetching fixture images from BitBag server...${NO_COLOR}\n\n" + mkdir -p var/fixtures + wget -O var/fixtures/images.zip https://demo.open-marketplace.io/images-compressed.zip?v=20230517 -q --show-progress +fi + +DIR=var/fixtures/images +if [ ! -d "$DIR" ]; then + printf "\n${BLUE}Unpacking ZIP${NO_COLOR}\n\n" + mkdir -p var/fixtures/images + unzip var/fixtures/images.zip -d var/fixtures/images > /dev/null 2>&1 +fi + +printf "\n${BLUE}Reloading fixtures${NO_COLOR}\n\n" +bin/console sylius:fixtures:load -n open_marketplace diff --git a/OpenMarketplace/composer.json b/OpenMarketplace/composer.json new file mode 100644 index 0000000..3a1535d --- /dev/null +++ b/OpenMarketplace/composer.json @@ -0,0 +1,85 @@ +{ + "name": "bitbag/open-marketplace", + "type": "project", + "description": "BitBag Multi-Vendor Marketplace Universe", + "license": "MIT", + "require": { + "php": "^8.0", + "bitbag/cms-plugin": "^3.2", + "bitbag/wishlist-plugin": "^3.0", + "doctrine/annotations": "^1.14", + "php-http/message-factory": "^1.1", + "ramsey/uuid-doctrine": "^1.8", + "sylius/sylius": "^1.11.12", + "symfony/dotenv": "^4.4 || ^5.2", + "symfony/flex": "^1.11", + "symfony/webpack-encore-bundle": "^1.15" + }, + "require-dev": { + "behat/behat": "^3.6.1", + "behat/mink-selenium2-driver": "^1.4", + "bitbag/coding-standard": "^v2.0.0", + "dmore/behat-chrome-extension": "^1.3", + "dmore/chrome-mink-driver": "^2.7", + "friends-of-behat/mink": "^1.8", + "friends-of-behat/mink-browserkit-driver": "^1.4", + "friends-of-behat/mink-debug-extension": "^2.0.0", + "friends-of-behat/mink-extension": "^2.4", + "friends-of-behat/page-object-extension": "^0.3", + "friends-of-behat/suite-settings-extension": "^1.0", + "friends-of-behat/symfony-extension": "^2.1", + "friends-of-behat/variadic-extension": "^1.3", + "lchrusciel/api-test-case": "^5.2", + "nelmio/alice": "^3.10", + "phpspec/phpspec": "^7.0", + "phpunit/phpunit": "^9.5", + "polishsymfonycommunity/symfony-mocker-container": "^1.0", + "symfony/browser-kit": "^4.4 || ^5.2", + "symfony/debug-bundle": "^4.4 || ^5.2", + "symfony/intl": "^4.4 || ^5.2", + "symfony/web-profiler-bundle": "^4.4 || ^5.2", + "phpstan/extension-installer": "^1.0", + "stripe/stripe-php": "^6.43", + "sylius-labs/coding-standard": "^4.0" + }, + "config": { + "preferred-install": { + "*": "dist" + }, + "sort-packages": true, + "allow-plugins": { + "symfony/thanks": false, + "dealerdirect/phpcodesniffer-composer-installer": false, + "phpstan/extension-installer": false, + "symfony/flex": true + } + }, + "autoload": { + "psr-4": { + "BitBag\\OpenMarketplace\\": "src/", + "App\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Tests\\BitBag\\OpenMarketplace\\": ["tests/"], + "Sylius\\Tests\\Api\\": ["vendor/sylius/sylius/tests/Api/"] + }, + "classmap": [ + "src/Kernel.php" + ] + }, + "prefer-stable": true, + "scripts": { + "post-install-cmd": [ + "@auto-scripts" + ], + "post-update-cmd": [ + "@auto-scripts" + ], + "auto-scripts": { + "cache:clear": "symfony-cmd", + "assets:install %PUBLIC_DIR%": "symfony-cmd" + } + } +} diff --git a/OpenMarketplace/config/api_platform/.gitignore b/OpenMarketplace/config/api_platform/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/OpenMarketplace/config/bootstrap.php b/OpenMarketplace/config/bootstrap.php new file mode 100644 index 0000000..1ba3a57 --- /dev/null +++ b/OpenMarketplace/config/bootstrap.php @@ -0,0 +1,21 @@ +=1.2) +if (is_array($env = @include dirname(__DIR__).'/.env.local.php')) { + $_SERVER += $env; + $_ENV += $env; +} elseif (!class_exists(Dotenv::class)) { + throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.'); +} else { + // load all the .env files + (new Dotenv(true))->loadEnv(dirname(__DIR__).'/.env'); +} + +$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev'; +$_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV']; +$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0'; diff --git a/OpenMarketplace/config/bundles.php b/OpenMarketplace/config/bundles.php new file mode 100644 index 0000000..8167f70 --- /dev/null +++ b/OpenMarketplace/config/bundles.php @@ -0,0 +1,65 @@ + ['all' => true], + Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], + Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], + Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle::class => ['all' => true], + Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], + Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], + Sylius\Bundle\OrderBundle\SyliusOrderBundle::class => ['all' => true], + Sylius\Bundle\MoneyBundle\SyliusMoneyBundle::class => ['all' => true], + Sylius\Bundle\CurrencyBundle\SyliusCurrencyBundle::class => ['all' => true], + Sylius\Calendar\SyliusCalendarBundle::class => ['all' => true], + Sylius\Bundle\LocaleBundle\SyliusLocaleBundle::class => ['all' => true], + Sylius\Bundle\ProductBundle\SyliusProductBundle::class => ['all' => true], + Sylius\Bundle\ChannelBundle\SyliusChannelBundle::class => ['all' => true], + Sylius\Bundle\AttributeBundle\SyliusAttributeBundle::class => ['all' => true], + Sylius\Bundle\TaxationBundle\SyliusTaxationBundle::class => ['all' => true], + Sylius\Bundle\ShippingBundle\SyliusShippingBundle::class => ['all' => true], + Sylius\Bundle\PaymentBundle\SyliusPaymentBundle::class => ['all' => true], + Sylius\Bundle\MailerBundle\SyliusMailerBundle::class => ['all' => true], + Sylius\Bundle\PromotionBundle\SyliusPromotionBundle::class => ['all' => true], + Sylius\Bundle\AddressingBundle\SyliusAddressingBundle::class => ['all' => true], + Sylius\Bundle\InventoryBundle\SyliusInventoryBundle::class => ['all' => true], + Sylius\Bundle\TaxonomyBundle\SyliusTaxonomyBundle::class => ['all' => true], + Sylius\Bundle\UserBundle\SyliusUserBundle::class => ['all' => true], + Sylius\Bundle\CustomerBundle\SyliusCustomerBundle::class => ['all' => true], + Sylius\Bundle\UiBundle\SyliusUiBundle::class => ['all' => true], + Sylius\Bundle\ReviewBundle\SyliusReviewBundle::class => ['all' => true], + Sylius\Bundle\CoreBundle\SyliusCoreBundle::class => ['all' => true], + Sylius\Bundle\ResourceBundle\SyliusResourceBundle::class => ['all' => true], + Sylius\Bundle\GridBundle\SyliusGridBundle::class => ['all' => true], + winzou\Bundle\StateMachineBundle\winzouStateMachineBundle::class => ['all' => true], + Sonata\BlockBundle\SonataBlockBundle::class => ['all' => true], + Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle::class => ['all' => true], + JMS\SerializerBundle\JMSSerializerBundle::class => ['all' => true], + FOS\RestBundle\FOSRestBundle::class => ['all' => true], + Knp\Bundle\GaufretteBundle\KnpGaufretteBundle::class => ['all' => true], + Knp\Bundle\MenuBundle\KnpMenuBundle::class => ['all' => true], + Liip\ImagineBundle\LiipImagineBundle::class => ['all' => true], + Payum\Bundle\PayumBundle\PayumBundle::class => ['all' => true], + Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], + Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true], + Sylius\Bundle\FixturesBundle\SyliusFixturesBundle::class => ['all' => true], + Sylius\Bundle\PayumBundle\SyliusPayumBundle::class => ['all' => true], + Sylius\Bundle\ThemeBundle\SyliusThemeBundle::class => ['all' => true], + Sylius\Bundle\AdminBundle\SyliusAdminBundle::class => ['all' => true], + Sylius\Bundle\ShopBundle\SyliusShopBundle::class => ['all' => true], + Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true, 'test_cached' => true], + Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true, 'test_cached' => true], + FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle::class => ['test' => true, 'test_cached' => true], + Sylius\Behat\Application\SyliusTestPlugin\SyliusTestPlugin::class => ['test' => true, 'test_cached' => true], + ApiPlatform\Core\Bridge\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true], + Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true], + Sylius\Bundle\ApiBundle\SyliusApiBundle::class => ['all' => true], + SyliusLabs\DoctrineMigrationsExtraBundle\SyliusLabsDoctrineMigrationsExtraBundle::class => ['all' => true], + Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], + Nelmio\Alice\Bridge\Symfony\NelmioAliceBundle::class => ['dev' => true, 'test' => true], + Fidry\AliceDataFixtures\Bridge\Symfony\FidryAliceDataFixturesBundle::class => ['dev' => true, 'test' => true], + BabDev\PagerfantaBundle\BabDevPagerfantaBundle::class => ['all' => true], + SyliusLabs\Polyfill\Symfony\Security\Bundle\SyliusLabsPolyfillSymfonySecurityBundle::class => ['all' => true], + FOS\CKEditorBundle\FOSCKEditorBundle::class => ['all' => true], + BitBag\SyliusCmsPlugin\BitBagSyliusCmsPlugin::class => ['all' => true], + BitBag\SyliusWishlistPlugin\BitBagSyliusWishlistPlugin::class => ['all' => true], +]; diff --git a/OpenMarketplace/config/jwt/.gitkeep b/OpenMarketplace/config/jwt/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/OpenMarketplace/config/jwt/private-test.pem b/OpenMarketplace/config/jwt/private-test.pem new file mode 100644 index 0000000..a679a9b --- /dev/null +++ b/OpenMarketplace/config/jwt/private-test.pem @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIrIQxXEW1GYsCAggA +MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECHhFnhqxP5H4BIIEyKDi67AJtZch +OKB/BXfhuBzI1SuUqg0zmFUYHHD2h1rsYrN5whcj4NgqBdNCNv7lXOgug5Rcu3jB +VV7Up6bkHSLwAguApyY1cbdt3iM9dhWw4mSUt7FUaq3dVWzFNdCV6hSSDsMUA2+M +Dvu4EXBvoeBbniU89qoyHSvSEC40Y17lOvafeUO2km8CGs+Wd++KB65c4HAibvdN +9q1H++BYYddyoGplybSTojp4Lxho8pRqG300g/ztO36PvKUYmRIm4/83tpejLdde +UFHBk0wDUcj/G3jsUj+azt13WyeekIEMvnwJx96gXOvXrnsovDzrsmKWCMvR4co1 +R27m9uhiUI5tWYj43g0GnNE0+qsMP64USQZSUQfUPVL8E1XG6qgjkGYkUXxNs2Rh +nqGO61MN+bNxdcdyeUpskGC+uI6RbwaWY/+8EDkgFdwp4mKZiYrucowL9JwJCAfq +nU6vRBcuj682kNFxyJpyWuPZdUr7iBrQ2OG+AkVrrSiydrOLt40TisRf84diB3pM +y++y/asTNpN2NsyoO/wvTbWCs1//0ckgtCAtRXe2BMJ0k6dzVMZ4m6iLuDwlYhjh +nsK/e/UgBUsT3jqw+RS1fs0LcuiHN4HnK1njt/w0kOg8mo4LHisXTg2IAHudsq2v +c9pKvbqHW0bRKk/Z93nCxGWH/OswWrAXlT3tNvaUpq577SB7NSrKmX7vFELwxA0X +eYzmc7+dUNHC+nlBakQJZF2ovloK22dtGBGEzpAPT7gkOBvxU4LJyb998WKNx2PI +W6ta/fFn/jfFU8KhQMvgePVBKsQNEVrGxEZGFOggFgbIfXvsJvfmGB/6JUj8IRoj +vjjrzFcBwL7Ri5gXMRvYs4kUs7EKVJ1vJOHLTdwWEQ1NkXKhJtu1+BT5L1d3o+u2 +cpZuZqYgPCiXY+WKMyrzFtcc4es0+rDnkC00hfNJFs2btTHXxSAdzU86lrSz7Vmc +voD7x3vZ/LjNkVlOMXasPBO8qhUnsTOXcsC5/Y4xtZZuXUnS6bBP2QDlUkNLrvLF +v0VsPun5MDxjihvfwY3B+/6vhzlgYqVTAiLksbCnc3hdoarjMJlQMI7XOsu6CHG9 +dKaNF4H/rJyEAUaDpdCpgCuDv2iUkQTpgfAKGB7PqU571/voMGz4TAlbfgXABb9K +s1mGg+jj7yTvhmeo5Z0Yw22gDcA62QQn7TQ5VS+kqsXIfg5BLRmwHqvXNOddQdEh +xvVeeI68LLlGyJ0/xRBwT3+A3oVE8hUaJV9iYsHGluQhNkbQYDtNlAhjT+nMO/WN +gd02ve+YdHimGF9ouz3YboX4WRO9BMUzXZMLKnbm5QiI8fO5m77rYo4CfTe3Idxn +AOLtbaF7iivJSBOqTa2+xz+yX97tZUcPYsRgEQgKQohw6wgC/FcI5uU7uIRRB4PS +xQpkXlTTB91nNkb6pS/t9ahbgPxk4sFkhRDO3gyiaMbY8XyulWRiB1sp3E6vum2u +t20WDP55/Gk5ww8l2jBe80euiJnfYbUhlo0j7KKOBMQG3tGI08GxwOPIX4WTTpnh +6TU0g/UDxmpWAzn3jTcVtkO8oDmoE6b2IUBE48NYZsScsbcSKsJfk/3zsOC0QIWj +oeBf+AvdHs5P6YRaqQMnSA== +-----END ENCRYPTED PRIVATE KEY----- diff --git a/OpenMarketplace/config/jwt/private.pem b/OpenMarketplace/config/jwt/private.pem new file mode 100644 index 0000000..a679a9b --- /dev/null +++ b/OpenMarketplace/config/jwt/private.pem @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIrIQxXEW1GYsCAggA +MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECHhFnhqxP5H4BIIEyKDi67AJtZch +OKB/BXfhuBzI1SuUqg0zmFUYHHD2h1rsYrN5whcj4NgqBdNCNv7lXOgug5Rcu3jB +VV7Up6bkHSLwAguApyY1cbdt3iM9dhWw4mSUt7FUaq3dVWzFNdCV6hSSDsMUA2+M +Dvu4EXBvoeBbniU89qoyHSvSEC40Y17lOvafeUO2km8CGs+Wd++KB65c4HAibvdN +9q1H++BYYddyoGplybSTojp4Lxho8pRqG300g/ztO36PvKUYmRIm4/83tpejLdde +UFHBk0wDUcj/G3jsUj+azt13WyeekIEMvnwJx96gXOvXrnsovDzrsmKWCMvR4co1 +R27m9uhiUI5tWYj43g0GnNE0+qsMP64USQZSUQfUPVL8E1XG6qgjkGYkUXxNs2Rh +nqGO61MN+bNxdcdyeUpskGC+uI6RbwaWY/+8EDkgFdwp4mKZiYrucowL9JwJCAfq +nU6vRBcuj682kNFxyJpyWuPZdUr7iBrQ2OG+AkVrrSiydrOLt40TisRf84diB3pM +y++y/asTNpN2NsyoO/wvTbWCs1//0ckgtCAtRXe2BMJ0k6dzVMZ4m6iLuDwlYhjh +nsK/e/UgBUsT3jqw+RS1fs0LcuiHN4HnK1njt/w0kOg8mo4LHisXTg2IAHudsq2v +c9pKvbqHW0bRKk/Z93nCxGWH/OswWrAXlT3tNvaUpq577SB7NSrKmX7vFELwxA0X +eYzmc7+dUNHC+nlBakQJZF2ovloK22dtGBGEzpAPT7gkOBvxU4LJyb998WKNx2PI +W6ta/fFn/jfFU8KhQMvgePVBKsQNEVrGxEZGFOggFgbIfXvsJvfmGB/6JUj8IRoj +vjjrzFcBwL7Ri5gXMRvYs4kUs7EKVJ1vJOHLTdwWEQ1NkXKhJtu1+BT5L1d3o+u2 +cpZuZqYgPCiXY+WKMyrzFtcc4es0+rDnkC00hfNJFs2btTHXxSAdzU86lrSz7Vmc +voD7x3vZ/LjNkVlOMXasPBO8qhUnsTOXcsC5/Y4xtZZuXUnS6bBP2QDlUkNLrvLF +v0VsPun5MDxjihvfwY3B+/6vhzlgYqVTAiLksbCnc3hdoarjMJlQMI7XOsu6CHG9 +dKaNF4H/rJyEAUaDpdCpgCuDv2iUkQTpgfAKGB7PqU571/voMGz4TAlbfgXABb9K +s1mGg+jj7yTvhmeo5Z0Yw22gDcA62QQn7TQ5VS+kqsXIfg5BLRmwHqvXNOddQdEh +xvVeeI68LLlGyJ0/xRBwT3+A3oVE8hUaJV9iYsHGluQhNkbQYDtNlAhjT+nMO/WN +gd02ve+YdHimGF9ouz3YboX4WRO9BMUzXZMLKnbm5QiI8fO5m77rYo4CfTe3Idxn +AOLtbaF7iivJSBOqTa2+xz+yX97tZUcPYsRgEQgKQohw6wgC/FcI5uU7uIRRB4PS +xQpkXlTTB91nNkb6pS/t9ahbgPxk4sFkhRDO3gyiaMbY8XyulWRiB1sp3E6vum2u +t20WDP55/Gk5ww8l2jBe80euiJnfYbUhlo0j7KKOBMQG3tGI08GxwOPIX4WTTpnh +6TU0g/UDxmpWAzn3jTcVtkO8oDmoE6b2IUBE48NYZsScsbcSKsJfk/3zsOC0QIWj +oeBf+AvdHs5P6YRaqQMnSA== +-----END ENCRYPTED PRIVATE KEY----- diff --git a/OpenMarketplace/config/jwt/public-test.pem b/OpenMarketplace/config/jwt/public-test.pem new file mode 100644 index 0000000..9a1a2a6 --- /dev/null +++ b/OpenMarketplace/config/jwt/public-test.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzE6CahgrutMYkFNdv6+M +wG8Hk/2283MDNqMHsTETgJ2zCOMCFkEuikFU6j4Vpn5C+MKZN/On90HqPdUEIn+A +v9yiNbuAdyQt9H77ldok9AWzYxNb0kVwk4EUYqCnnb6BKLM4GT1TIwppV5MvQPHX +Bs3/ujsrhg7Z9OqPORE8J3kLM1+JqxAiljT/vmLSgZfL2J6B6XuQhecMLpTvTFZy +mR96UWj29u8kVwr/KObDlGIuInMN/GIPPdiivggoDk7I13+jmKe88ZNyOytpHIim +FeDEXZK2meqwzErYfo4J13GYBPKaX1JmMKna+ZjmNObL09iHmUa4BXKzgSvAdD6I +NQIDAQAB +-----END PUBLIC KEY----- diff --git a/OpenMarketplace/config/jwt/public.pem b/OpenMarketplace/config/jwt/public.pem new file mode 100644 index 0000000..9a1a2a6 --- /dev/null +++ b/OpenMarketplace/config/jwt/public.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzE6CahgrutMYkFNdv6+M +wG8Hk/2283MDNqMHsTETgJ2zCOMCFkEuikFU6j4Vpn5C+MKZN/On90HqPdUEIn+A +v9yiNbuAdyQt9H77ldok9AWzYxNb0kVwk4EUYqCnnb6BKLM4GT1TIwppV5MvQPHX +Bs3/ujsrhg7Z9OqPORE8J3kLM1+JqxAiljT/vmLSgZfL2J6B6XuQhecMLpTvTFZy +mR96UWj29u8kVwr/KObDlGIuInMN/GIPPdiivggoDk7I13+jmKe88ZNyOytpHIim +FeDEXZK2meqwzErYfo4J13GYBPKaX1JmMKna+ZjmNObL09iHmUa4BXKzgSvAdD6I +NQIDAQAB +-----END PUBLIC KEY----- diff --git a/OpenMarketplace/config/packages/_sylius.yaml b/OpenMarketplace/config/packages/_sylius.yaml new file mode 100644 index 0000000..36d1bed --- /dev/null +++ b/OpenMarketplace/config/packages/_sylius.yaml @@ -0,0 +1,114 @@ +imports: + - { resource: "@SyliusCoreBundle/Resources/config/app/config.yml" } + + - { resource: "@BitBagSyliusCmsPlugin/Resources/config/config.yml" } + - { resource: "@BitBagSyliusWishlistPlugin/Resources/config/config.yml" } + + - { resource: "@SyliusAdminBundle/Resources/config/app/config.yml" } + - { resource: "@SyliusApiBundle/Resources/config/app/config.yaml" } + + - { resource: "@SyliusShopBundle/Resources/config/app/config.yml" } + + - { resource: "./../../src/Component/Core/Admin/Resources/config.yaml" } + - { resource: "./../../src/Component/Core/Common/Resources/config.yaml" } + - { resource: "./../../src/Component/Core/Shop/Resources/config.yaml" } + - { resource: "./../../src/Component/Core/Vendor/Resources/config.yaml" } + - { resource: "./../../src/Component/Core/Settlement/Resources/config.yaml" } + - { resource: "./../../src/Component/Messaging/Resources/config.yaml" } + - { resource: "./../../src/Component/Override/Resources/config.yaml" } + +parameters: + sylius_core.public_dir: '%kernel.project_dir%/public' + +sylius_shop: + product_grid: + include_all_descendants: true + +sylius_order: + resources: + order: + classes: + model: BitBag\OpenMarketplace\Component\Order\Entity\Order + controller: BitBag\OpenMarketplace\Component\Core\Common\Controller\Resource\OrderController + repository: BitBag\OpenMarketplace\Component\Order\Repository\OrderRepository + form: Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType\OrderType + order_item: + classes: + model: BitBag\OpenMarketplace\Component\Order\Entity\OrderItem + +sylius_product: + resources: + product: + classes: + model: BitBag\OpenMarketplace\Component\Product\Entity\Product + interface: BitBag\OpenMarketplace\Component\Product\Entity\ProductInterface + repository: BitBag\OpenMarketplace\Component\Product\Repository\ProductRepository + product_variant: + classes: + repository: BitBag\OpenMarketplace\Component\Product\Repository\ProductVariantRepository + +sylius_user: + resources: + shop: + user: + classes: + model: BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser + interface: BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUserInterface + +sylius_shipping: + resources: + shipment: + classes: + model: BitBag\OpenMarketplace\Component\Order\Entity\Shipment + interface: BitBag\OpenMarketplace\Component\Order\Entity\ShipmentInterface + repository: BitBag\OpenMarketplace\Component\Order\Repository\ShipmentRepository + +sylius_payment: + resources: + payment: + classes: + repository: BitBag\OpenMarketplace\Component\Order\Repository\PaymentRepository + +sylius_customer: + resources: + customer: + classes: + repository: BitBag\OpenMarketplace\Component\Vendor\Repository\CustomerRepository + +sylius_review: + resources: + product: + review: + classes: + repository: BitBag\OpenMarketplace\Component\Product\Repository\ProductReviewRepository + +sylius_taxonomy: + resources: + taxon: + classes: + model: Sylius\Component\Core\Model\Taxon + repository: BitBag\OpenMarketplace\Component\Vendor\Repository\TaxonRepository + +sylius_channel: + resources: + channel: + classes: + repository: BitBag\OpenMarketplace\Component\Channel\Repository\ChannelRepository + +sylius_ui: + events: + sylius.shop.checkout.header: + blocks: + before_header_legacy: + template: "@SyliusUi/Block/_legacySonataEvent.html.twig" + priority: 15 + context: + event: sylius.shop.checkout.address.before_header # Intentionally using "address" event for backwards compatibility + header: + template: "@SyliusShop/Checkout/_header.html.twig" + priority: 10 + after_header_legacy: + template: "@SyliusUi/Block/_legacySonataEvent.html.twig" + priority: 5 + context: + event: sylius.shop.checkout.address.after_header # Intentionally using "address" event for backwards compatibility diff --git a/OpenMarketplace/config/packages/api_platform.yaml b/OpenMarketplace/config/packages/api_platform.yaml new file mode 100644 index 0000000..eac321a --- /dev/null +++ b/OpenMarketplace/config/packages/api_platform.yaml @@ -0,0 +1,15 @@ +api_platform: + mapping: + paths: + - '%kernel.project_dir%/vendor/sylius/sylius/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources' + - '%kernel.project_dir%/config/api_platform' + - '%kernel.project_dir%/src/Component/Core/Api/Resources/api_resources' + - '%kernel.project_dir%/src/Component/Messaging/Entity' + - '%kernel.project_dir%/src/Component/Order/Entity' + - '%kernel.project_dir%/src/Component/Product/Entity' + - '%kernel.project_dir%/src/Component/ProductListing/Entity' + - '%kernel.project_dir%/src/Component/Vendor/Entity' + patch_formats: + json: ['application/merge-patch+json'] + swagger: + versions: [3] diff --git a/OpenMarketplace/config/packages/assets.yaml b/OpenMarketplace/config/packages/assets.yaml new file mode 100644 index 0000000..9e2edaa --- /dev/null +++ b/OpenMarketplace/config/packages/assets.yaml @@ -0,0 +1,15 @@ +framework: + assets: + packages: + shop: + json_manifest_path: '%kernel.project_dir%/public/build/shop/manifest.json' + admin: + json_manifest_path: '%kernel.project_dir%/public/build/admin/manifest.json' + cms_shop: + json_manifest_path: '%kernel.project_dir%/public/build/bitbag/cms/shop/manifest.json' + cms_admin: + json_manifest_path: '%kernel.project_dir%/public/build/bitbag/cms/admin/manifest.json' + wishlist_shop: + json_manifest_path: '%kernel.project_dir%/public/build/bitbag/wishlist/shop/manifest.json' + wishlist_admin: + json_manifest_path: '%kernel.project_dir%/public/build/bitbag/wishlist/admin/manifest.json' diff --git a/OpenMarketplace/config/packages/dev/_sylius.yaml b/OpenMarketplace/config/packages/dev/_sylius.yaml new file mode 100644 index 0000000..cd01aaf --- /dev/null +++ b/OpenMarketplace/config/packages/dev/_sylius.yaml @@ -0,0 +1,2 @@ +sylius_api: + enabled: true diff --git a/OpenMarketplace/config/packages/dev/framework.yaml b/OpenMarketplace/config/packages/dev/framework.yaml new file mode 100644 index 0000000..4b116de --- /dev/null +++ b/OpenMarketplace/config/packages/dev/framework.yaml @@ -0,0 +1,2 @@ +framework: + profiler: { only_exceptions: false } diff --git a/OpenMarketplace/config/packages/dev/jms_serializer.yaml b/OpenMarketplace/config/packages/dev/jms_serializer.yaml new file mode 100644 index 0000000..2f32a9b --- /dev/null +++ b/OpenMarketplace/config/packages/dev/jms_serializer.yaml @@ -0,0 +1,12 @@ +jms_serializer: + visitors: + json_serialization: + options: + - JSON_PRETTY_PRINT + - JSON_UNESCAPED_SLASHES + - JSON_PRESERVE_ZERO_FRACTION + json_deserialization: + options: + - JSON_PRETTY_PRINT + - JSON_UNESCAPED_SLASHES + - JSON_PRESERVE_ZERO_FRACTION diff --git a/OpenMarketplace/config/packages/dev/monolog.yaml b/OpenMarketplace/config/packages/dev/monolog.yaml new file mode 100644 index 0000000..da2b092 --- /dev/null +++ b/OpenMarketplace/config/packages/dev/monolog.yaml @@ -0,0 +1,9 @@ +monolog: + handlers: + main: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: debug + firephp: + type: firephp + level: info diff --git a/OpenMarketplace/config/packages/dev/nelmio_alice.yaml b/OpenMarketplace/config/packages/dev/nelmio_alice.yaml new file mode 100644 index 0000000..e2ae069 --- /dev/null +++ b/OpenMarketplace/config/packages/dev/nelmio_alice.yaml @@ -0,0 +1,3 @@ +nelmio_alice: + functions_blacklist: + - 'current' diff --git a/OpenMarketplace/config/packages/dev/routing.yaml b/OpenMarketplace/config/packages/dev/routing.yaml new file mode 100644 index 0000000..4116679 --- /dev/null +++ b/OpenMarketplace/config/packages/dev/routing.yaml @@ -0,0 +1,3 @@ +framework: + router: + strict_requirements: true diff --git a/OpenMarketplace/config/packages/dev/swiftmailer.yaml b/OpenMarketplace/config/packages/dev/swiftmailer.yaml new file mode 100644 index 0000000..8ca953b --- /dev/null +++ b/OpenMarketplace/config/packages/dev/swiftmailer.yaml @@ -0,0 +1,2 @@ +swiftmailer: + disable_delivery: false diff --git a/OpenMarketplace/config/packages/dev/web_profiler.yaml b/OpenMarketplace/config/packages/dev/web_profiler.yaml new file mode 100644 index 0000000..1f1cb2b --- /dev/null +++ b/OpenMarketplace/config/packages/dev/web_profiler.yaml @@ -0,0 +1,3 @@ +web_profiler: + toolbar: true + intercept_redirects: false diff --git a/OpenMarketplace/config/packages/doctrine.yaml b/OpenMarketplace/config/packages/doctrine.yaml new file mode 100644 index 0000000..0b56496 --- /dev/null +++ b/OpenMarketplace/config/packages/doctrine.yaml @@ -0,0 +1,50 @@ +parameters: + # Adds a fallback DATABASE_URL if the env var is not set. + # This allows you to run cache:warmup even if your + # environment variables are not available yet. + # You should not need to change this value. + env(DATABASE_URL): '' + +doctrine: + dbal: + driver: 'pdo_mysql' + server_version: '5.7' + charset: UTF8 + url: '%env(resolve:DATABASE_URL)%' + types: + uuid: 'Ramsey\Uuid\Doctrine\UuidType' + orm: + auto_generate_proxy_classes: '%kernel.debug%' + naming_strategy: doctrine.orm.naming_strategy.underscore + auto_mapping: true + mappings: + MessagingComponent: + is_bundle: false + type: xml + dir: '%kernel.project_dir%/src/Component/Messaging/Resources/doctrine' + prefix: 'BitBag\OpenMarketplace\Component\Messaging\Entity' + OrderComponent: + is_bundle: false + type: xml + dir: '%kernel.project_dir%/src/Component/Order/Resources/doctrine' + prefix: 'BitBag\OpenMarketplace\Component\Order\Entity' + ProductComponent: + is_bundle: false + type: xml + dir: '%kernel.project_dir%/src/Component/Product/Resources/doctrine' + prefix: 'BitBag\OpenMarketplace\Component\Product\Entity' + ProductListingComponent: + is_bundle: false + type: xml + dir: '%kernel.project_dir%/src/Component/ProductListing/Resources/doctrine' + prefix: 'BitBag\OpenMarketplace\Component\ProductListing\Entity' + VendorComponent: + is_bundle: false + type: xml + dir: '%kernel.project_dir%/src/Component/Vendor/Resources/doctrine' + prefix: 'BitBag\OpenMarketplace\Component\Vendor\Entity' + SettlementComponent: + is_bundle: false + type: xml + dir: '%kernel.project_dir%/src/Component/Settlement/Resources/doctrine' + prefix: 'BitBag\OpenMarketplace\Component\Settlement\Entity' diff --git a/OpenMarketplace/config/packages/doctrine_migrations.yaml b/OpenMarketplace/config/packages/doctrine_migrations.yaml new file mode 100644 index 0000000..765b5c5 --- /dev/null +++ b/OpenMarketplace/config/packages/doctrine_migrations.yaml @@ -0,0 +1,6 @@ +doctrine_migrations: + storage: + table_storage: + table_name: sylius_migrations + migrations_paths: + 'App\Migrations': "%kernel.project_dir%/src/Migrations" diff --git a/OpenMarketplace/config/packages/fos_rest.yaml b/OpenMarketplace/config/packages/fos_rest.yaml new file mode 100644 index 0000000..eaebb27 --- /dev/null +++ b/OpenMarketplace/config/packages/fos_rest.yaml @@ -0,0 +1,11 @@ +fos_rest: + exception: true + view: + formats: + json: true + xml: true + empty_content: 204 + format_listener: + rules: + - { path: '^/api/v1/.*', priorities: ['json', 'xml'], fallback_format: json, prefer_extension: true } + - { path: '^/', stop: true } diff --git a/OpenMarketplace/config/packages/framework.yaml b/OpenMarketplace/config/packages/framework.yaml new file mode 100644 index 0000000..33e332e --- /dev/null +++ b/OpenMarketplace/config/packages/framework.yaml @@ -0,0 +1,10 @@ +framework: + translator: { fallbacks: ["%locale%"] } + secret: '%env(APP_SECRET)%' + form: true + csrf_protection: true + session: + handler_id: ~ + serializer: + mapping: + paths: [ '%kernel.project_dir%/config/serialization', '%kernel.project_dir%/src/Component/Core/Api/Resources/serialization' ] diff --git a/OpenMarketplace/config/packages/jms_serializer.yaml b/OpenMarketplace/config/packages/jms_serializer.yaml new file mode 100644 index 0000000..ed7bc61 --- /dev/null +++ b/OpenMarketplace/config/packages/jms_serializer.yaml @@ -0,0 +1,4 @@ +jms_serializer: + visitors: + xml_serialization: + format_output: '%kernel.debug%' diff --git a/OpenMarketplace/config/packages/lexik_jwt_authentication.yaml b/OpenMarketplace/config/packages/lexik_jwt_authentication.yaml new file mode 100644 index 0000000..edfb69d --- /dev/null +++ b/OpenMarketplace/config/packages/lexik_jwt_authentication.yaml @@ -0,0 +1,4 @@ +lexik_jwt_authentication: + secret_key: '%env(resolve:JWT_SECRET_KEY)%' + public_key: '%env(resolve:JWT_PUBLIC_KEY)%' + pass_phrase: '%env(JWT_PASSPHRASE)%' diff --git a/OpenMarketplace/config/packages/liip_imagine.yaml b/OpenMarketplace/config/packages/liip_imagine.yaml new file mode 100644 index 0000000..dbbb24d --- /dev/null +++ b/OpenMarketplace/config/packages/liip_imagine.yaml @@ -0,0 +1,14 @@ +liip_imagine: + resolvers: + default: + web_path: + web_root: "%kernel.project_dir%/public" + cache_prefix: "media/cache" + + filter_sets: + open_marketplace_fixture_size: + filters: + thumbnail: { size: [800, 600], mode: outbound } + open_marketplace_vendor_background: + filters: + thumbnail: { size: [1155, 200], mode: outbound } diff --git a/OpenMarketplace/config/packages/monolog.yaml b/OpenMarketplace/config/packages/monolog.yaml new file mode 100644 index 0000000..08bf08c --- /dev/null +++ b/OpenMarketplace/config/packages/monolog.yaml @@ -0,0 +1,10 @@ +monolog: + channels: + - 'settlements_email' + handlers: + settlements_email: + type: stream + level: debug + path: "%kernel.logs_dir%/settlements_email_%kernel.environment%.log" + channels: + - 'settlements_email' diff --git a/OpenMarketplace/config/packages/prod/doctrine.yaml b/OpenMarketplace/config/packages/prod/doctrine.yaml new file mode 100644 index 0000000..e2951fc --- /dev/null +++ b/OpenMarketplace/config/packages/prod/doctrine.yaml @@ -0,0 +1,36 @@ +doctrine: + orm: + entity_managers: + default: + metadata_cache_driver: + type: service + id: doctrine.system_cache_provider + query_cache_driver: + type: service + id: doctrine.system_cache_provider + result_cache_driver: + type: service + id: doctrine.result_cache_provider + dbal: + types: + uuid: 'Ramsey\Uuid\Doctrine\UuidType' + +services: + doctrine.result_cache_provider: + class: Symfony\Component\Cache\DoctrineProvider + public: false + arguments: + - '@doctrine.result_cache_pool' + doctrine.system_cache_provider: + class: Symfony\Component\Cache\DoctrineProvider + public: false + arguments: + - '@doctrine.system_cache_pool' + +framework: + cache: + pools: + doctrine.result_cache_pool: + adapter: cache.app + doctrine.system_cache_pool: + adapter: cache.system diff --git a/OpenMarketplace/config/packages/prod/jms_serializer.yaml b/OpenMarketplace/config/packages/prod/jms_serializer.yaml new file mode 100644 index 0000000..c288182 --- /dev/null +++ b/OpenMarketplace/config/packages/prod/jms_serializer.yaml @@ -0,0 +1,10 @@ +jms_serializer: + visitors: + json_serialization: + options: + - JSON_UNESCAPED_SLASHES + - JSON_PRESERVE_ZERO_FRACTION + json_deserialization: + options: + - JSON_UNESCAPED_SLASHES + - JSON_PRESERVE_ZERO_FRACTION diff --git a/OpenMarketplace/config/packages/prod/monolog.yaml b/OpenMarketplace/config/packages/prod/monolog.yaml new file mode 100644 index 0000000..6461211 --- /dev/null +++ b/OpenMarketplace/config/packages/prod/monolog.yaml @@ -0,0 +1,10 @@ +monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: nested + nested: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: debug diff --git a/OpenMarketplace/config/packages/routing.yaml b/OpenMarketplace/config/packages/routing.yaml new file mode 100644 index 0000000..368bc7f --- /dev/null +++ b/OpenMarketplace/config/packages/routing.yaml @@ -0,0 +1,3 @@ +framework: + router: + strict_requirements: ~ diff --git a/OpenMarketplace/config/packages/security.yaml b/OpenMarketplace/config/packages/security.yaml new file mode 100644 index 0000000..1c9f7c3 --- /dev/null +++ b/OpenMarketplace/config/packages/security.yaml @@ -0,0 +1,150 @@ +parameters: + sylius.security.admin_regex: "^/%sylius_admin.path_name%" + sylius.security.shop_regex: "^/(?!%sylius_admin.path_name%|api/.*|api$|media/.*)[^/]++" + sylius.security.new_api_route: "/api/v2" + sylius.security.new_api_regex: "^%sylius.security.new_api_route%" + sylius.security.new_api_admin_route: "%sylius.security.new_api_route%/admin" + sylius.security.new_api_admin_regex: "^%sylius.security.new_api_admin_route%" + sylius.security.new_api_shop_route: "%sylius.security.new_api_route%/shop" + sylius.security.new_api_shop_regex: "^%sylius.security.new_api_shop_route%" + sylius.security.new_api_user_account_route: "%sylius.security.new_api_shop_route%/account" + sylius.security.new_api_user_account_regex: "^%sylius.security.new_api_user_account_route%" + sylius.security.new_api_user_account_vendor_route: "%sylius.security.new_api_user_account_route%/vendor" + sylius.security.new_api_user_account_vendor_regex: "^%sylius.security.new_api_user_account_vendor_route%" + +security: + always_authenticate_before_granting: true + providers: + sylius_admin_user_provider: + id: sylius.admin_user_provider.email_or_name_based + sylius_api_admin_user_provider: + id: sylius.admin_user_provider.email_or_name_based + sylius_shop_user_provider: + id: sylius.shop_user_provider.email_or_name_based + sylius_api_shop_user_provider: + id: sylius.shop_user_provider.email_or_name_based + + encoders: + Sylius\Component\User\Model\UserInterface: argon2i + firewalls: + admin: + switch_user: true + context: admin + pattern: "%sylius.security.admin_regex%" + provider: sylius_admin_user_provider + form_login: + provider: sylius_admin_user_provider + login_path: sylius_admin_login + check_path: sylius_admin_login_check + failure_path: sylius_admin_login + default_target_path: sylius_admin_dashboard + use_forward: false + use_referer: true + csrf_token_generator: security.csrf.token_manager + csrf_parameter: _csrf_admin_security_token + csrf_token_id: admin_authenticate + remember_me: + secret: "%env(APP_SECRET)%" + path: "/%sylius_admin.path_name%" + name: APP_ADMIN_REMEMBER_ME + lifetime: 31536000 + remember_me_parameter: _remember_me + logout: + path: sylius_admin_logout + target: sylius_admin_login + anonymous: true + + new_api_admin_user: + pattern: "%sylius.security.new_api_admin_regex%/.*" + provider: sylius_api_admin_user_provider + stateless: true + anonymous: true + json_login: + check_path: "%sylius.security.new_api_admin_route%/authentication-token" + username_path: email + password_path: password + success_handler: lexik_jwt_authentication.handler.authentication_success + failure_handler: lexik_jwt_authentication.handler.authentication_failure + guard: + authenticators: + - lexik_jwt_authentication.jwt_token_authenticator + + new_api_shop_user: + pattern: "%sylius.security.new_api_shop_regex%/.*" + provider: sylius_api_shop_user_provider + stateless: true + anonymous: true + json_login: + check_path: "%sylius.security.new_api_shop_route%/authentication-token" + username_path: email + password_path: password + success_handler: lexik_jwt_authentication.handler.authentication_success + failure_handler: lexik_jwt_authentication.handler.authentication_failure + guard: + authenticators: + - lexik_jwt_authentication.jwt_token_authenticator + + shop: + switch_user: { role: ROLE_ALLOWED_TO_SWITCH } + context: shop + pattern: "%sylius.security.shop_regex%" + provider: sylius_shop_user_provider + form_login: + success_handler: sylius.authentication.success_handler + failure_handler: sylius.authentication.failure_handler + provider: sylius_shop_user_provider + login_path: sylius_shop_login + check_path: sylius_shop_login_check + failure_path: sylius_shop_login + default_target_path: sylius_shop_homepage + use_forward: false + use_referer: true + csrf_token_generator: security.csrf.token_manager + csrf_parameter: _csrf_shop_security_token + csrf_token_id: shop_authenticate + remember_me: + secret: "%env(APP_SECRET)%" + name: APP_SHOP_REMEMBER_ME + lifetime: 31536000 + remember_me_parameter: _remember_me + logout: + path: sylius_shop_logout + target: sylius_shop_login + invalidate_session: false + success_handler: sylius.handler.shop_user_logout + anonymous: true + + dev: + pattern: ^/(_(profiler|wdt)|css|images|js)/ + security: false + + image_resolver: + pattern: ^/media/cache/resolve + security: false + + access_control: + - { path: "%sylius.security.admin_regex%/_partial", role: IS_AUTHENTICATED_ANONYMOUSLY, ips: [127.0.0.1, ::1] } + - { path: "%sylius.security.admin_regex%/_partial", role: ROLE_NO_ACCESS } + - { path: "%sylius.security.shop_regex%/_partial", role: IS_AUTHENTICATED_ANONYMOUSLY, ips: [127.0.0.1, ::1] } + - { path: "%sylius.security.shop_regex%/_partial", role: ROLE_NO_ACCESS } + + - { path: "%sylius.security.admin_regex%/login", role: IS_AUTHENTICATED_ANONYMOUSLY } + - { path: "%sylius.security.shop_regex%/login", role: IS_AUTHENTICATED_ANONYMOUSLY } + + - { path: "%sylius.security.shop_regex%/register", role: IS_AUTHENTICATED_ANONYMOUSLY } + - { path: "%sylius.security.shop_regex%/verify", role: IS_AUTHENTICATED_ANONYMOUSLY } + + - { path: "%sylius.security.admin_regex%", role: ROLE_ADMINISTRATION_ACCESS } + - { path: "%sylius.security.shop_regex%/account/vendor/conversation/create", role: ROLE_USER } + - { path: "%sylius.security.shop_regex%/account/vendor/conversations", role: ROLE_USER } + - { path: "%sylius.security.shop_regex%/account/vendor/register", role: ROLE_USER } + - { path: "%sylius.security.shop_regex%/account/vendor", role: ROLE_VENDOR } + - { path: "%sylius.security.shop_regex%/account", role: ROLE_USER } + + - { path: "%sylius.security.new_api_admin_regex%/.*", role: ROLE_API_ACCESS } + - { path: "%sylius.security.new_api_admin_route%/authentication-token", role: IS_AUTHENTICATED_ANONYMOUSLY } + - { path: "%sylius.security.new_api_user_account_vendor_regex%/register", role: ROLE_USER } + - { path: "%sylius.security.new_api_user_account_vendor_regex%", role: ROLE_VENDOR } + - { path: "%sylius.security.new_api_user_account_regex%/.*", role: ROLE_USER } + - { path: "%sylius.security.new_api_shop_route%/authentication-token", role: IS_AUTHENTICATED_ANONYMOUSLY } + - { path: "%sylius.security.new_api_shop_regex%/.*", role: IS_AUTHENTICATED_ANONYMOUSLY } diff --git a/OpenMarketplace/config/packages/staging/monolog.yaml b/OpenMarketplace/config/packages/staging/monolog.yaml new file mode 100644 index 0000000..6461211 --- /dev/null +++ b/OpenMarketplace/config/packages/staging/monolog.yaml @@ -0,0 +1,10 @@ +monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: nested + nested: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: debug diff --git a/OpenMarketplace/config/packages/staging/swiftmailer.yaml b/OpenMarketplace/config/packages/staging/swiftmailer.yaml new file mode 100644 index 0000000..f438078 --- /dev/null +++ b/OpenMarketplace/config/packages/staging/swiftmailer.yaml @@ -0,0 +1,2 @@ +swiftmailer: + disable_delivery: true diff --git a/OpenMarketplace/config/packages/stof_doctrine_extensions.yaml b/OpenMarketplace/config/packages/stof_doctrine_extensions.yaml new file mode 100644 index 0000000..7770f74 --- /dev/null +++ b/OpenMarketplace/config/packages/stof_doctrine_extensions.yaml @@ -0,0 +1,4 @@ +# Read the documentation: https://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html +# See the official DoctrineExtensions documentation for more details: https://github.com/Atlantic18/DoctrineExtensions/tree/master/doc/ +stof_doctrine_extensions: + default_locale: '%locale%' diff --git a/OpenMarketplace/config/packages/swiftmailer.yaml b/OpenMarketplace/config/packages/swiftmailer.yaml new file mode 100644 index 0000000..3bab0d3 --- /dev/null +++ b/OpenMarketplace/config/packages/swiftmailer.yaml @@ -0,0 +1,2 @@ +swiftmailer: + url: '%env(MAILER_URL)%' diff --git a/OpenMarketplace/config/packages/sylius_labs_doctrine_migrations_extra.yaml b/OpenMarketplace/config/packages/sylius_labs_doctrine_migrations_extra.yaml new file mode 100644 index 0000000..3150dd9 --- /dev/null +++ b/OpenMarketplace/config/packages/sylius_labs_doctrine_migrations_extra.yaml @@ -0,0 +1,3 @@ +sylius_labs_doctrine_migrations_extra: + migrations: + 'App\Migrations': ~ diff --git a/OpenMarketplace/config/packages/test/fidry_alice_data_fixtures.yaml b/OpenMarketplace/config/packages/test/fidry_alice_data_fixtures.yaml new file mode 100644 index 0000000..ae4e694 --- /dev/null +++ b/OpenMarketplace/config/packages/test/fidry_alice_data_fixtures.yaml @@ -0,0 +1,2 @@ +fidry_alice_data_fixtures: + default_purge_mode: no_purge diff --git a/OpenMarketplace/config/packages/test/framework.yaml b/OpenMarketplace/config/packages/test/framework.yaml new file mode 100644 index 0000000..76d7e5e --- /dev/null +++ b/OpenMarketplace/config/packages/test/framework.yaml @@ -0,0 +1,4 @@ +framework: + test: ~ + session: + storage_id: session.storage.mock_file diff --git a/OpenMarketplace/config/packages/test/monolog.yaml b/OpenMarketplace/config/packages/test/monolog.yaml new file mode 100644 index 0000000..7e2b9e3 --- /dev/null +++ b/OpenMarketplace/config/packages/test/monolog.yaml @@ -0,0 +1,6 @@ +monolog: + handlers: + main: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: error diff --git a/OpenMarketplace/config/packages/test/nelmio_alice.yaml b/OpenMarketplace/config/packages/test/nelmio_alice.yaml new file mode 100644 index 0000000..caec543 --- /dev/null +++ b/OpenMarketplace/config/packages/test/nelmio_alice.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: ../dev/nelmio_alice.yaml } diff --git a/OpenMarketplace/config/packages/test/security.yaml b/OpenMarketplace/config/packages/test/security.yaml new file mode 100644 index 0000000..c04de4d --- /dev/null +++ b/OpenMarketplace/config/packages/test/security.yaml @@ -0,0 +1,7 @@ +security: + encoders: + sha512: sha512 + Sylius\Component\User\Model\UserInterface: sha512 + +sylius_user: + encoder: sha512 diff --git a/OpenMarketplace/config/packages/test/swiftmailer.yaml b/OpenMarketplace/config/packages/test/swiftmailer.yaml new file mode 100644 index 0000000..c438f4b --- /dev/null +++ b/OpenMarketplace/config/packages/test/swiftmailer.yaml @@ -0,0 +1,6 @@ +swiftmailer: + disable_delivery: true + logging: true + spool: + type: file + path: "%kernel.cache_dir%/spool" diff --git a/OpenMarketplace/config/packages/test/sylius_theme.yaml b/OpenMarketplace/config/packages/test/sylius_theme.yaml new file mode 100644 index 0000000..4d34199 --- /dev/null +++ b/OpenMarketplace/config/packages/test/sylius_theme.yaml @@ -0,0 +1,3 @@ +sylius_theme: + sources: + test: ~ diff --git a/OpenMarketplace/config/packages/test/sylius_uploader.yaml b/OpenMarketplace/config/packages/test/sylius_uploader.yaml new file mode 100644 index 0000000..ab9d6ca --- /dev/null +++ b/OpenMarketplace/config/packages/test/sylius_uploader.yaml @@ -0,0 +1,3 @@ +services: + Sylius\Component\Core\Generator\ImagePathGeneratorInterface: + class: Sylius\Behat\Service\Generator\UploadedImagePathGenerator diff --git a/OpenMarketplace/config/packages/test/web_profiler.yaml b/OpenMarketplace/config/packages/test/web_profiler.yaml new file mode 100644 index 0000000..03752de --- /dev/null +++ b/OpenMarketplace/config/packages/test/web_profiler.yaml @@ -0,0 +1,6 @@ +web_profiler: + toolbar: false + intercept_redirects: false + +framework: + profiler: { collect: false } diff --git a/OpenMarketplace/config/packages/test_cached/doctrine.yaml b/OpenMarketplace/config/packages/test_cached/doctrine.yaml new file mode 100644 index 0000000..ac3ee6f --- /dev/null +++ b/OpenMarketplace/config/packages/test_cached/doctrine.yaml @@ -0,0 +1,33 @@ +doctrine: + orm: + entity_managers: + default: + metadata_cache_driver: + type: service + id: doctrine.system_cache_provider + query_cache_driver: + type: service + id: doctrine.system_cache_provider + result_cache_driver: + type: service + id: doctrine.result_cache_provider + +services: + doctrine.result_cache_provider: + class: Symfony\Component\Cache\DoctrineProvider + public: false + arguments: + - '@doctrine.result_cache_pool' + doctrine.system_cache_provider: + class: Symfony\Component\Cache\DoctrineProvider + public: false + arguments: + - '@doctrine.system_cache_pool' + +framework: + cache: + pools: + doctrine.result_cache_pool: + adapter: cache.app + doctrine.system_cache_pool: + adapter: cache.system diff --git a/OpenMarketplace/config/packages/test_cached/fidry_alice_data_fixtures.yaml b/OpenMarketplace/config/packages/test_cached/fidry_alice_data_fixtures.yaml new file mode 100644 index 0000000..ae4e694 --- /dev/null +++ b/OpenMarketplace/config/packages/test_cached/fidry_alice_data_fixtures.yaml @@ -0,0 +1,2 @@ +fidry_alice_data_fixtures: + default_purge_mode: no_purge diff --git a/OpenMarketplace/config/packages/test_cached/fos_rest.yaml b/OpenMarketplace/config/packages/test_cached/fos_rest.yaml new file mode 100644 index 0000000..2b4189d --- /dev/null +++ b/OpenMarketplace/config/packages/test_cached/fos_rest.yaml @@ -0,0 +1,3 @@ +fos_rest: + exception: + debug: true diff --git a/OpenMarketplace/config/packages/test_cached/framework.yaml b/OpenMarketplace/config/packages/test_cached/framework.yaml new file mode 100644 index 0000000..76d7e5e --- /dev/null +++ b/OpenMarketplace/config/packages/test_cached/framework.yaml @@ -0,0 +1,4 @@ +framework: + test: ~ + session: + storage_id: session.storage.mock_file diff --git a/OpenMarketplace/config/packages/test_cached/monolog.yaml b/OpenMarketplace/config/packages/test_cached/monolog.yaml new file mode 100644 index 0000000..7e2b9e3 --- /dev/null +++ b/OpenMarketplace/config/packages/test_cached/monolog.yaml @@ -0,0 +1,6 @@ +monolog: + handlers: + main: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: error diff --git a/OpenMarketplace/config/packages/test_cached/security.yaml b/OpenMarketplace/config/packages/test_cached/security.yaml new file mode 100644 index 0000000..c04de4d --- /dev/null +++ b/OpenMarketplace/config/packages/test_cached/security.yaml @@ -0,0 +1,7 @@ +security: + encoders: + sha512: sha512 + Sylius\Component\User\Model\UserInterface: sha512 + +sylius_user: + encoder: sha512 diff --git a/OpenMarketplace/config/packages/test_cached/swiftmailer.yaml b/OpenMarketplace/config/packages/test_cached/swiftmailer.yaml new file mode 100644 index 0000000..c438f4b --- /dev/null +++ b/OpenMarketplace/config/packages/test_cached/swiftmailer.yaml @@ -0,0 +1,6 @@ +swiftmailer: + disable_delivery: true + logging: true + spool: + type: file + path: "%kernel.cache_dir%/spool" diff --git a/OpenMarketplace/config/packages/test_cached/sylius_channel.yaml b/OpenMarketplace/config/packages/test_cached/sylius_channel.yaml new file mode 100644 index 0000000..bab83ef --- /dev/null +++ b/OpenMarketplace/config/packages/test_cached/sylius_channel.yaml @@ -0,0 +1,2 @@ +sylius_channel: + debug: true diff --git a/OpenMarketplace/config/packages/test_cached/sylius_theme.yaml b/OpenMarketplace/config/packages/test_cached/sylius_theme.yaml new file mode 100644 index 0000000..4d34199 --- /dev/null +++ b/OpenMarketplace/config/packages/test_cached/sylius_theme.yaml @@ -0,0 +1,3 @@ +sylius_theme: + sources: + test: ~ diff --git a/OpenMarketplace/config/packages/test_cached/sylius_uploader.yaml b/OpenMarketplace/config/packages/test_cached/sylius_uploader.yaml new file mode 100644 index 0000000..cfa727e --- /dev/null +++ b/OpenMarketplace/config/packages/test_cached/sylius_uploader.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: "../test/sylius_uploader.yaml" } diff --git a/OpenMarketplace/config/packages/test_cached/twig.yaml b/OpenMarketplace/config/packages/test_cached/twig.yaml new file mode 100644 index 0000000..8c6e0b4 --- /dev/null +++ b/OpenMarketplace/config/packages/test_cached/twig.yaml @@ -0,0 +1,2 @@ +twig: + strict_variables: true diff --git a/OpenMarketplace/config/packages/test_cached/web_profiler.yaml b/OpenMarketplace/config/packages/test_cached/web_profiler.yaml new file mode 100644 index 0000000..9052e3a --- /dev/null +++ b/OpenMarketplace/config/packages/test_cached/web_profiler.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: "../test/web_profiler.yaml" } diff --git a/OpenMarketplace/config/packages/translation.yaml b/OpenMarketplace/config/packages/translation.yaml new file mode 100644 index 0000000..1f4f966 --- /dev/null +++ b/OpenMarketplace/config/packages/translation.yaml @@ -0,0 +1,8 @@ +framework: + default_locale: '%locale%' + translator: + paths: + - '%kernel.project_dir%/translations' + fallbacks: + - '%locale%' + - 'en' diff --git a/OpenMarketplace/config/packages/twig.yaml b/OpenMarketplace/config/packages/twig.yaml new file mode 100644 index 0000000..fd74dd5 --- /dev/null +++ b/OpenMarketplace/config/packages/twig.yaml @@ -0,0 +1,19 @@ +twig: + paths: ['%kernel.project_dir%/templates'] + debug: '%kernel.debug%' + strict_variables: '%kernel.debug%' + globals: + base_vendor_logo_path: '%env(LOGO_DIRECTORY)%' + vendor_products_limits: '%env(VENDOR_PRODUCTS_LIMITS)%' + default_vendor_products_limit: '%env(DEFAULT_VENDOR_PRODUCTS_LIMIT)%' + form_themes: + - '@FOSCKEditor/Form/ckeditor_widget.html.twig' + - '@BitBagSyliusCmsPlugin/Form/ckeditor_widget.html.twig' + +services: + _defaults: + public: false + autowire: true + autoconfigure: true + + Twig\Extra\Intl\IntlExtension: ~ diff --git a/OpenMarketplace/config/packages/validator.yaml b/OpenMarketplace/config/packages/validator.yaml new file mode 100644 index 0000000..4d863c1 --- /dev/null +++ b/OpenMarketplace/config/packages/validator.yaml @@ -0,0 +1,10 @@ +framework: + validation: + enable_annotations: true + mapping: + paths: + - '%kernel.project_dir%/src/Component/Core/Api/Resources/validation/' + - '%kernel.project_dir%/src/Component/Core/Shop/Resources/validation/' + - '%kernel.project_dir%/src/Component/Messaging/Resources/validation/' + - '%kernel.project_dir%/src/Component/ProductListing/Resources/validation/' + - '%kernel.project_dir%/src/Component/Vendor/Resources/validation/' diff --git a/OpenMarketplace/config/packages/webpack_encore.yaml b/OpenMarketplace/config/packages/webpack_encore.yaml new file mode 100644 index 0000000..1ea8774 --- /dev/null +++ b/OpenMarketplace/config/packages/webpack_encore.yaml @@ -0,0 +1,9 @@ +webpack_encore: + output_path: '%kernel.project_dir%/public/build/default' + builds: + shop: '%kernel.project_dir%/public/build/shop' + admin: '%kernel.project_dir%/public/build/admin' + cms_shop: '%kernel.project_dir%/public/build/bitbag/cms/shop' + cms_admin: '%kernel.project_dir%/public/build/bitbag/cms/admin' + wishlist_shop: '%kernel.project_dir%/public/build/bitbag/wishlist/shop' + wishlist_admin: '%kernel.project_dir%/public/build/bitbag/wishlist/admin' diff --git a/OpenMarketplace/config/preload.php b/OpenMarketplace/config/preload.php new file mode 100644 index 0000000..5ebcdb2 --- /dev/null +++ b/OpenMarketplace/config/preload.php @@ -0,0 +1,5 @@ +8.0 | +| sylius/sylius | 1.11.x | +| MySQL | \>= 5.7 | + +---- + +The Open Marketplace application can serve as a foundation for your custom e-commerce marketplace application. + +Before creating your application, make sure you use at least PHP 8.0 and have Composer installed. + +**Be aware. The project has currently a strong reference to Sylius eCommerce platform. If you have not discovered the solution yet, it is worth at least taking a look at the official Sylius documentation.** + +### 1. Create project + +```diff +$ composer create-project bitbag/open-marketplace project +$ cd project +``` + +Open Marketplace as an application based on Sylius is using environment variables which configure connection +with database, mailer services, vendor products limits, vendor logo directory +and directory of files uploaded through messages. Default values are stored in `.env` file +and you can customise them by creating `.env.local` file with variables that you want to change. + + > For mailer to work properly you need to customise `MAILER_URL` in your `env.local` + + > For database to work properly you need to customise `DATABASE_URL` in your `env.local` with your database credentials + +Creating database for your project + +```diff +$ bin/console doctrine:database:create +$ bin/console doctrine:schema:create +``` +### 2. Install & build assets + +```diff +$ yarn install +$ yarn encore dev +$ bin/console assets:install +``` +You can also use `yarn watch` to observe and build resources after saving files. + +### 3. Run the app + +```diff +$ symfony server:start // or symfony serve -d --no-tls +``` + +### 4. Load fixtures + +```diff +$ bin/fixtures +``` + +**Note: If you do not want to use our mockup data and prefer a clean installation instead, follow the Sylius installation guide [here](https://docs.sylius.com/en/latest/getting-started-with-sylius/installation.html#project-setup:~:text=To%20launch%20a%20Sylius%20application%20initial%20data%20has%20to%20be%20set%20up%3A%20an%20administrator%20account%20and%20base%20locale.%20Run%20the%20Sylius%20installation%20command%20to%20do%20that.).** + +## Optional steps + +### 5. Run tests + +Creating database for your test environment. + +```diff +$ bin/console doctrine:database:create --env=test +$ bin/console doctrine:schema:create --env=test +``` + +**a)** PHPUnit + +```diff +vendor/bin/phpunit --colors=always tests/ +``` +**b)** PHPSpec + +```diff +vendor/bin/phpspec run +``` + +**c)** PHPStan + +```diff +vendor/bin/phpstan analyse -c phpstan.neon -l 8 src/ +``` + +**d)** Behat + +```diff +vendor/bin/behat +``` + +**e)** Coding Standard + +```diff +vendor/bin/ecs check src +``` diff --git a/OpenMarketplace/doc/manage_clients.md b/OpenMarketplace/doc/manage_clients.md new file mode 100644 index 0000000..2c28221 --- /dev/null +++ b/OpenMarketplace/doc/manage_clients.md @@ -0,0 +1,24 @@ +## Manage Clients + +As a registered vendor, you can manage clients who have placed orders with you. + +Clients you will find in vendor menu in your account (1). + +![Clients in vendor menu](images/manage_clients.png) + +### Clients List + +On this section you will find yours clients list with basic data of each one. + +![Clients list](images/clients_list.png) + +### Manage each client + +If you want see more details about client you can click show button(1) in actions column + +![Clients show button](images/clients_show_button.png) + +In client details View you can see Customer data(1) and his address information(2). +You can also click show orders button to see his orders placed with you. + +![Clients show button](images/client-details.png) diff --git a/OpenMarketplace/doc/manage_orders.md b/OpenMarketplace/doc/manage_orders.md new file mode 100644 index 0000000..a8d36bf --- /dev/null +++ b/OpenMarketplace/doc/manage_orders.md @@ -0,0 +1,32 @@ +## Manage Client Orders + +As a registered vendor, you can manage orders from your customers. + +Orders you will find in vendor menu in your account (1). + +![Orders in vendor menu](images/manage_orders.png) + +### Orders List + +In this section you will find orders list with its basic data respectively. + +![Orders list](images/orders_list.png) + +### Manage each order + +If you want see more details of a given order you can click show button(1) in the actions column + +![Orders show button](images/orders_show_button.png) + +In order details view you can see order info (1) and items (2). + +![Order basic data](images/order_info.png) + +Below there is information about shipping method (1). + +![Shipping information](images/shipping_info.png) + +Next information about `payments` (1), `customer` (2) and `adresses` (3). +You can also manage shipments (4) and resend confirmation email to client (5). + +![Order details](images/order_details.png) \ No newline at end of file diff --git a/OpenMarketplace/doc/manage_product_reviews.md b/OpenMarketplace/doc/manage_product_reviews.md new file mode 100644 index 0000000..941ddae --- /dev/null +++ b/OpenMarketplace/doc/manage_product_reviews.md @@ -0,0 +1,27 @@ +## Manage Product Reviews + +As a registered vendor, you can manage reviews of your products. + +Reviews you will find in vendor menu in your account. + +![Reviews in vendor menu](images/reviews/menu.png) + +### Product Review List + +In this section you will find product reviews list with its basic data respectively. + +![Reviews list](images/reviews/list.png) + +### Manage each product review + +If you want to edit a product review you can click `Edit` (1) button in dropdown menu of `Details`. +Then you can change `Title` (1) and `Comment` (2) of the product review, and you can +see information about product (3) and customer (4). + +![Edit review](images/reviews/edit.png) +![Review edit page](images/reviews/edit_page.png) + +You can also `Accept`(1), `Reject`(2) and `Delete`(3) product reviews. +If you accept a product review, then the review will be available at product's page. + +![Accept review](images/reviews/details.png) diff --git a/OpenMarketplace/doc/manage_shipping_methods.md b/OpenMarketplace/doc/manage_shipping_methods.md new file mode 100644 index 0000000..64e0242 --- /dev/null +++ b/OpenMarketplace/doc/manage_shipping_methods.md @@ -0,0 +1,11 @@ +## Manage Shipping Methods + +Only a registered vendor can manage available shipping methods for customers. + +Shipping Methods can be found in vendor menu in vendor account (1). + +![Shipping methods in vendor menu](images/shipping_methods.png) + +On the Shipping Methods page, vendor can enable or disable available methods using switch before each courier (1) + +![Manage shipping Methods](images/manage_shipping_methods.png) diff --git a/OpenMarketplace/doc/managing_settlements_with_vendors.md b/OpenMarketplace/doc/managing_settlements_with_vendors.md new file mode 100644 index 0000000..8a0cff1 --- /dev/null +++ b/OpenMarketplace/doc/managing_settlements_with_vendors.md @@ -0,0 +1,93 @@ +## Settlements + +### Introduction + +--- + +When a customer makes a payment for an order, the entire amount is meant to be transferred to administrator's account. +Each order carries a commission, and vendors can initiate the withdrawal of their earnings through the settlement process. +This approach ensures a controlled and transparent financial ecosystem, providing administrators and vendors with flexibility over their financial transactions. + +`OpenMarketplace` does not automatically transfer funds from the administrator to vendor accounts. +However, it is possible to integrate it with other payment gateways and automate the process of transferring funds to the vendor's account . + +### Settlement frequency + +--- + +Administrator can assign different settlement frequencies to vendors. +Settlements are generated based on the assigned frequency and contain information about the period the settlement covers. +For example, with a weekly settlement frequency, settlements are generated every week, covering the transactions paid previous week. +The inclusion factor for a particular period is defined by the `paidAt` property of the `Order` entity. + +Settlements might be generated for the following frequencies: +- `weekly` - settlements are generated every week, +- `monthly` - settlements are generated every month, +- `quarterly` - settlements are generated every quarter, + +Important note: Frequencies are dictating periods for which settlements are generated. +Weekly settlement will be generated for previous week, monthly for previous month and quarterly for previous quarter. +Profit for orders paid in this settlement frequency period will be settled in the next settlement frequency period. + +E.g. If you have weekly settlement frequency, settlement for `2024-01-01` - `2024-01-07` will be generated during first run of command after `2024-01-07 23:59:59`. +This settlement will contain all orders paid between `2024-01-01 00:00:00` and `2024-01-07 23:59:59`. + +To generate settlements, use `/docker/cron/crontab` file, make sure it contains line : +``` bash +0 9 * * 1 php /srv/sylius/bin/console bitbag:settlement:generate +``` + +#### Settlement frequency categories + +Settlements can be divided into 2 categories based on the way they are created. +All settlement frequencies mentioned above are `cyclical` - they are generated by cron job. +However, there is one more `non-cyclical` settlement frequency- `virtual_wallet`. +Non-cyclical settlements are generated by vendor. + +### States + +--- + +Settlements have 3 available states, which are managed by state machine: +- `new` - the settlement is generated and not yet accepted by the seller, +- `accepted` - the settlement is accepted by the seller but not yet marked as paid, +- `settled` - the settlement is paid, + +### Transitions + +--- + +The state machine has 2 transitions: +- `accept` - moves the settlement from `new` to `accepted` when settlement for given period is accepted by the seller, +- `settle` - moves the settlement from `accepted` to `paid` when the settlement is paid, + +### Payment gateway integration + +--- + +Out-of-the-box state machine applies `settle` transition during `accept` callback in `SettlementCallbacks`. + +```php +final class SettlementCallbacks implements SettlementCallbacksInterface +{ + public function __construct( + private SettlementStateMachineTransitionInterface $settlementStateMachineTransition, + private EntityManagerInterface $entityManager, + ) { + } + + public function payout(SettlementInterface $settlement): void + { + $this->settlementStateMachineTransition->applyIfCan( + $settlement, + SettlementTransitions::SETTLE, + ); + + $this->entityManager->flush(); + } +} +``` + +If you want to integrate OpenMarketplace with payment gateway, the best way is to override `SettlementCallbacks::payout`. +There you can implement logic responsible for payout processing. + For the best result you should apply `settle` transition after successful payout confirmation. diff --git a/OpenMarketplace/doc/order_process.md b/OpenMarketplace/doc/order_process.md new file mode 100644 index 0000000..91c4f07 --- /dev/null +++ b/OpenMarketplace/doc/order_process.md @@ -0,0 +1,10 @@ +## Order process from several vendors + +When a customer buys products from the different vendors, he can choose the shipping method for each of them separately + +the photo below shows the available shipping methods for thetwo different companies "Company" (1) and "Second Company" (2) + +![Shipping methods for each vendor](images/shipping_methods_for_each_vendor.png) + +When customer places the order each vendor will have a separate order from this customer. + diff --git a/OpenMarketplace/doc/product_listings.md b/OpenMarketplace/doc/product_listings.md new file mode 100644 index 0000000..a1c8b44 --- /dev/null +++ b/OpenMarketplace/doc/product_listings.md @@ -0,0 +1,74 @@ +## Product listing creation + +Registered vendor can create product listing by visiting +Product list page (1). +And click create product button (2). + +![product_listing_inex](images/product_listing_index.png) + +Then vendor have to fill up product listing form. + +In order to add attribute to product vendor have to +[create attribute](#adding-attributes) first. + +![product_form](images/product_form.png) + +After saving form, vendor can edit it or send to verification by application +administrator. After sending for verification editing product is blocked. + +![dropdown](images/dropdown.png) + +![status](images/status.png) + +Then it is up to the admin to decide whether the product list is rejected or +the product becomes available to the customer in the market, the admin can view +list of products sent for verification in the administration panel via the product listings tab (1). Each product listing has a detail page +where admin can view product details and decide whether to accept it or not (2). + +![admin_product_view](images/admin_product_view.png) + +## Product listing verification + +1. ### Rejecting product + If administrator decide to reject product, message containing + information why product was rejected is sent to vendor, also the status + of the product listing is set to rejected. + + ![conversation](images/conversation.png) + + Vendor can discuss this reason, or edit product and send updates for another verification. + +2. ### Accepting product + If administrator accepts product listing it becomes converted to the product + available for the customers. + + #### Details view + + ![details_view](images/details.png) + +## Product listing versioning + +Any changes made after accepting product have to be accepted by +administrator once again. + +## Adding attributes + +In order to add attribute to product listing vendor have to create it +first, by filling form (1) available from attributes management page (2). + +![attributes](images/attributes.png) + +Then every attribute created by vendor can be added to product listing. + +![adding_attribute](images/adding_attribute.png) + +## Inventory tab +This tab displays all accepted products of the vendor, every product can +be set to tracking mode. + +![inventory](images/inventory.png) + +If product is set to tracked the application will not allow buying product when +quantity reaches 0, + +![inventory_tracker_message](images/inventory_guard.png) diff --git a/OpenMarketplace/doc/vendor-profile.md b/OpenMarketplace/doc/vendor-profile.md new file mode 100644 index 0000000..3dc2ce1 --- /dev/null +++ b/OpenMarketplace/doc/vendor-profile.md @@ -0,0 +1,51 @@ +## Vendor profile + +### Becoming a vendor + +--- +Firstly, you need to register as a user. To do it you have to click `Register` button and complete the form: + +![registration.png](images/registration.png) + +After sending the form and confirming registration through email, you need to log in and click `My Account` (1) to see your user profile. +Now you can see `Become a Vendor` (2) button. Click it and complete the form. + +![become-a-vendor.png](images/become-a-vendor.png) +![vendor-form.png](images/vendor-form.png) + + +Registration as a Vendor have to be accepted by the administrator. As an administrator you have to go to admin panel and look for `Marketplace` category. +Under `Marketplace` you can se `Vendors` (1) tab which contains all vendors registered whether they are verified or not. To verify a vendor you need to go to `Details` (2) +in their row and click `Verify` button. After completing this step, an email will be sent to vendor with information that they have been verified. + +![vendors.png](images/vendors.png) +![verify.png](images/verify.png) + +Verified vendor is able to see his panel which contains features such as attributes, product list, inventory, +orders, clients, shipping methods, [conversations](conversations.md), profile. + + +### Editing vendor profile + +--- +Vendor can edit his company data provided in registration in `Profile` (1) tab after clicking `Edit` (2) button. To confirm the submitted changes, vendor will need to click the link send via email. The appropriate message with the guidelines will be dispayed. + +![profile-edit.png](images/profile-edit.png) +![edit-profile.png](images/edit-profile.png) + +Vendor has to confirm changes made in profile via email before editing it again. + +![edited-profile.png](images/edited-profile.png) + +### Deleting vendor + +--- +Administrator can delete vendor by clicking `Delete` (2) button in admin panel under `Vendors` (1) tab in `Marketplace`. +After this, administrator will have to confirm this action by clicking `Yes` (3) in a pop up. + +![delete-vendor.png](images/delete-vendor.png) +![delete-vendor-confirm.png](images/delete-vendor-confirm.png) + +User account will not be deleted after this action, and the user can apply again to become a vendor (in their profile). + + diff --git a/OpenMarketplace/docker-compose.prod.yml b/OpenMarketplace/docker-compose.prod.yml new file mode 100644 index 0000000..e76ea45 --- /dev/null +++ b/OpenMarketplace/docker-compose.prod.yml @@ -0,0 +1,110 @@ +services: + php: + container_name: php + build: + context: . + target: open_marketplace_php_prod + depends_on: + - migrations + environment: + APP_DEBUG: 0 + APP_ENV: prod + APP_SECRET: EDITME + DATABASE_URL: mysql://open_marketplace:${MYSQL_PASSWORD}@mysql/open_marketplace_prod + MAILER_URL: smtp://localhost + MESSENGER_TRANSPORT_DSN: doctrine://default + PHP_DATE_TIMEZONE: ${PHP_DATE_TIMEZONE:-UTC} + volumes: + # use a bind-mounted host directory, as we want to keep the sessions + - ./var/sessions:/srv/open_marketplace/var/sessions:rw + # use a bind-mounted host directory, as we want to keep the media + - ./public/media:/srv/open_marketplace/public/media:rw + networks: + - open_marketplace + + cron: + container_name: cron + build: + context: . + target: open_marketplace_cron + depends_on: + - migrations + environment: + APP_ENV: prod + APP_DEBUG: 0 + APP_SECRET: EDITME + DATABASE_URL: mysql://open_marketplace:${MYSQL_PASSWORD}@mysql/open_marketplace_prod + PHP_DATE_TIMEZONE: ${PHP_DATE_TIMEZONE:-UTC} + networks: + - open_marketplace + + worker: + container_name: worker + command: ["php", "bin/console", "messenger:consume", "main", "catalog_promotion_removal", "--limit=5", "--memory-limit=256M", "--time-limit=600"] + restart: always + build: + context: . + target: open_marketplace_php_prod + depends_on: + - migrations + environment: + APP_ENV: prod + APP_DEBUG: 0 + APP_SECRET: EDITME + DATABASE_URL: mysql://open_marketplace:${MYSQL_PASSWORD}@mysql/open_marketplace_prod + MESSENGER_TRANSPORT_DSN: doctrine://default + PHP_DATE_TIMEZONE: ${PHP_DATE_TIMEZONE:-UTC} + networks: + - open_marketplace + + migrations: + container_name: migrations + build: + context: . + target: open_marketplace_migrations_prod + depends_on: + - mysql + environment: + APP_ENV: prod + APP_DEBUG: 0 + APP_SECRET: EDITME + DATABASE_URL: mysql://open_marketplace:${MYSQL_PASSWORD}@mysql/open_marketplace_prod + LOAD_FIXTURES: ${LOAD_FIXTURES:-0} + PHP_DATE_TIMEZONE: ${PHP_DATE_TIMEZONE:-UTC} + networks: + - open_marketplace + + mysql: + container_name: mysql + # in production, we may want to use a managed database service + image: mysql:5.7 # Sylius is fully working on mysql 8.0 version + environment: + MYSQL_RANDOM_ROOT_PASSWORD: true + MYSQL_DATABASE: open_marketplace_prod + MYSQL_USER: open_marketplace + MYSQL_PASSWORD: ${MYSQL_PASSWORD:?MYSQL_PASSWORD is not set or empty} + volumes: + # use a bind-mounted host directory, because we never want to lose our data! + - ./docker/mysql/data:/var/lib/mysql:rw,delegated + networks: + - open_marketplace + + nginx: + container_name: nginx + # in production, we may want to use a static website hosting service + build: + context: . + target: open_marketplace_nginx + depends_on: + - php + volumes: + # use a bind-mounted host directory, as we want to keep the media + - ./public/media:/srv/open_marketplace/public/media:ro + networks: + - open_marketplace + ports: + - 80:80 + +networks: + open_marketplace: + driver: bridge diff --git a/OpenMarketplace/docker-compose.yml b/OpenMarketplace/docker-compose.yml new file mode 100644 index 0000000..373d2cf --- /dev/null +++ b/OpenMarketplace/docker-compose.yml @@ -0,0 +1,109 @@ +services: + php: + container_name: php + build: + context: . + target: open_marketplace_php_dev + depends_on: + - migrations + environment: + - APP_ENV=dev + - APP_DEBUG=1 + - APP_SECRET=EDITME + - DATABASE_URL=mysql://open_marketplace:${MYSQL_PASSWORD:-nopassword}@mysql/open_marketplace + - MAILER_URL=smtp://mailhog:1025 + - PHP_DATE_TIMEZONE=${PHP_DATE_TIMEZONE:-UTC} + volumes: + - .:/srv/open_marketplace:rw,cached + # if you develop on Linux, you may use a bind-mounted host directory instead + - ./var:/srv/open_marketplace/var:rw +# - ./public:/srv/open_marketplace/public:rw,delegated + # if you develop on Linux, you may use a bind-mounted host directory instead + # - ./public/media:/srv/open_marketplace/public/media:rw + - public-media:/srv/open_marketplace/public/media:rw + - fixture-images:/srv/open_marketplace/var/fixtures + + migrations: + container_name: migrations + build: + context: . + target: open_marketplace_migrations_dev + depends_on: + - mysql + environment: + - APP_ENV=dev + - APP_DEBUG=1 + - APP_SECRET=EDITME + - DATABASE_URL=mysql://open_marketplace:${MYSQL_PASSWORD:-nopassword}@mysql/open_marketplace + - LOAD_FIXTURES=1 + - PHP_DATE_TIMEZONE=${PHP_DATE_TIMEZONE:-UTC} + volumes: + - public-media:/srv/open_marketplace/public/media:rw + - fixture-images:/srv/open_marketplace/var/fixtures + + mysql: + container_name: mysql + image: mysql:5.7 # Sylius is fully working on mysql 8.0 version + platform: linux/amd64 + environment: + - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-nopassword} + - MYSQL_DATABASE=open_marketplace + - MYSQL_USER=open_marketplace + - MYSQL_PASSWORD=${MYSQL_PASSWORD:-nopassword} + volumes: + - mysql-data:/var/lib/mysql:rw + # you may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data! + # - ./docker/mysql/data:/var/lib/mysql:rw,delegated + ports: + - "${MYSQL_PORT:-3306}:3306" + cap_add: + - SYS_NICE # prevent "mbind: Operation not permitted" errors + + node: + container_name: node + build: + context: . + target: open_marketplace_node + command: ["yarn", "watch"] + depends_on: + - php + environment: + - GULP_ENV=dev + - PHP_HOST=php + - PHP_PORT=9000 + volumes: + - .:/srv/open_marketplace:rw,cached + - ./public:/srv/open_marketplace/public:rw,delegated + ports: + - "${NODE_PORT:-35729}:35729" + + nginx: + container_name: nginx + build: + context: . + target: open_marketplace_nginx + depends_on: + - php + - node # to ensure correct build order + volumes: + - ./public:/srv/open_marketplace/public:ro + # if you develop on Linux, you may use a bind-mounted host directory instead + # - ./public/media:/srv/open_marketplace/public/media:ro + - public-media:/srv/open_marketplace/public/media:ro,nocopy + ports: + - "${HTTP_PORT:-80}:80" + + mailhog: + # do not use in production! + image: mailhog/mailhog:latest + environment: + - MH_STORAGE=maildir + # volumes: + # - ./docker/mailhog/maildir:/maildir:rw,delegated + ports: + - "${MAILHOG_PORT:-8025}:8025" + +volumes: + mysql-data: + public-media: + fixture-images: diff --git a/OpenMarketplace/docker/cron/crontab b/OpenMarketplace/docker/cron/crontab new file mode 100644 index 0000000..5f1e579 --- /dev/null +++ b/OpenMarketplace/docker/cron/crontab @@ -0,0 +1,3 @@ +* * * * * php /srv/sylius/bin/console sylius:remove-expired-carts +* * * * * php /srv/sylius/bin/console sylius:cancel-unpaid-orders +0 9 * * 1 php /srv/sylius/bin/console bitbag:settlement:generate diff --git a/OpenMarketplace/docker/cron/docker-entrypoint.sh b/OpenMarketplace/docker/cron/docker-entrypoint.sh new file mode 100755 index 0000000..360a4f9 --- /dev/null +++ b/OpenMarketplace/docker/cron/docker-entrypoint.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -e + +while ping -c1 migrations >/dev/null 2>&1; +do + (>&2 echo "Waiting for Migrations container to finish") + sleep 1; +done; + +(>&2 echo "Migrations container finished. Starting Cron process.") + +exec docker-php-entrypoint "$@" diff --git a/OpenMarketplace/docker/migrations/docker-entrypoint.sh b/OpenMarketplace/docker/migrations/docker-entrypoint.sh new file mode 100755 index 0000000..5a32871 --- /dev/null +++ b/OpenMarketplace/docker/migrations/docker-entrypoint.sh @@ -0,0 +1,29 @@ +#!/bin/sh +set -e + +attempt_left=20 + +until php bin/console doctrine:query:sql "select 1" >/dev/null 2>&1; +do + attempt_left=$((attempt_left-1)) + + if [ "${attempt_left}" -eq "0" ]; then + + (>&2 echo "MySQL did not answer. Aborting migrations.") + exit 1 + else + (>&2 echo "Waiting for MySQL to be ready...") + fi + + sleep 1 +done + +php bin/console doctrine:database:create --if-not-exists --no-interaction + +php bin/console doctrine:schema:create + +if [ "$LOAD_FIXTURES" = "1" ]; then + sh bin/fixtures +fi + + diff --git a/OpenMarketplace/docker/nginx/conf.d/default.conf b/OpenMarketplace/docker/nginx/conf.d/default.conf new file mode 100644 index 0000000..01a87cf --- /dev/null +++ b/OpenMarketplace/docker/nginx/conf.d/default.conf @@ -0,0 +1,43 @@ +server { + root /srv/open_marketplace/public; + listen *:80; + + location / { + # try to serve file directly, fallback to index.php + try_files $uri /index.php$is_args$args; + } + + location ~ ^/index\.php(/|$) { + resolver 127.0.0.11 valid=10s ipv6=off; + set $backendfpm "php:9000"; + # Comment the next line and uncomment the next to enable dynamic resolution (incompatible with Kubernetes); + fastcgi_pass $backendfpm; + #resolver 127.0.0.11; + #set $upstream_host php; + #fastcgi_pass $upstream_host:9000; + + fastcgi_split_path_info ^(.+\.php)(/.*)$; + include fastcgi_params; + # When you are using symlinks to link the document root to the + # current version of your application, you should pass the real + # application path instead of the path to the symlink to PHP + # FPM. + # Otherwise, PHP's OPcache may not properly detect changes to + # your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126 + # for more information). + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + fastcgi_param DOCUMENT_ROOT $realpath_root; + # Prevents URIs that include the front controller. This will 404: + # http://domain.tld/index.php/some-path + # Remove the internal directive to allow URIs like this + internal; + } + + # return 404 for all other php files not matching the front controller + # this prevents access to other php files you don't want to be accessible. + location ~ \.php$ { + return 404; + } + + client_max_body_size 6m; +} diff --git a/OpenMarketplace/docker/node/docker-entrypoint.sh b/OpenMarketplace/docker/node/docker-entrypoint.sh new file mode 100755 index 0000000..69b60f6 --- /dev/null +++ b/OpenMarketplace/docker/node/docker-entrypoint.sh @@ -0,0 +1,19 @@ +#!/bin/sh +set -e + +# first arg is `-f` or `--some-option` +if [ "${1#-}" != "$1" ]; then + set -- node "$@" +fi + +if [ "$1" = 'node' ] || [ "$1" = 'yarn' ]; then + yarn install + npm rebuild node-sass + + >&2 echo "Waiting for PHP to be ready..." + until nc -z "$PHP_HOST" "$PHP_PORT"; do + sleep 1 + done +fi + +exec "$@" diff --git a/OpenMarketplace/docker/php/dev/opcache.ini b/OpenMarketplace/docker/php/dev/opcache.ini new file mode 100644 index 0000000..b6a356a --- /dev/null +++ b/OpenMarketplace/docker/php/dev/opcache.ini @@ -0,0 +1,10 @@ +[opcache] +opcache.enable=1 +opcache.enable_cli=1 +opcache.memory_consumption=256 +opcache.max_accelerated_files=20000 +opcache.validate_timestamps=1 +opcache.revalidate_freq=0 +opcache.jit=1255 +opcache.jit_buffer_size=128M +opcache.interned_strings_buffer=16 diff --git a/OpenMarketplace/docker/php/dev/php.ini b/OpenMarketplace/docker/php/dev/php.ini new file mode 100644 index 0000000..fc1acf9 --- /dev/null +++ b/OpenMarketplace/docker/php/dev/php.ini @@ -0,0 +1,7 @@ +memory_limit=3G +post_max_size=6M +upload_max_filesize=5M +realpath_cache_size=4096K +realpath_cache_ttl=600 + +date.timezone=${PHP_DATE_TIMEZONE} diff --git a/OpenMarketplace/docker/php/docker-entrypoint.sh b/OpenMarketplace/docker/php/docker-entrypoint.sh new file mode 100755 index 0000000..54b400a --- /dev/null +++ b/OpenMarketplace/docker/php/docker-entrypoint.sh @@ -0,0 +1,27 @@ +#!/bin/sh +set -e + +# first arg is `-f` or `--some-option` +if [ "${1#-}" != "$1" ]; then + set -- php-fpm "$@" +fi + +if [ "$1" = 'php-fpm' ] || [ "$1" = 'bin/console' ]; then + mkdir -p var/cache var/log var/sessions public/media + setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var public/media + setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var public/media + + if [ "$APP_ENV" != 'prod' ]; then + composer install --prefer-dist --no-progress --no-interaction + bin/console assets:install --no-interaction + bin/console sylius:theme:assets:install public --no-interaction + fi + + while ping -c1 migrations >/dev/null 2>&1; + do + (>&2 echo "Waiting for Migrations container to finish") + sleep 1; + done; +fi + +exec docker-php-entrypoint "$@" diff --git a/OpenMarketplace/docker/php/prod/opcache.ini b/OpenMarketplace/docker/php/prod/opcache.ini new file mode 100644 index 0000000..58be9e0 --- /dev/null +++ b/OpenMarketplace/docker/php/prod/opcache.ini @@ -0,0 +1,9 @@ +[opcache] +opcache.enable=1 +opcache.enable_cli=1 +opcache.memory_consumption=256 +opcache.max_accelerated_files=20000 +opcache.validate_timestamps=0 +opcache.jit=1255 +opcache.jit_buffer_size=128M +opcache.interned_strings_buffer=16 diff --git a/OpenMarketplace/docker/php/prod/php.ini b/OpenMarketplace/docker/php/prod/php.ini new file mode 100644 index 0000000..31170a7 --- /dev/null +++ b/OpenMarketplace/docker/php/prod/php.ini @@ -0,0 +1,7 @@ +memory_limit=256M +post_max_size=6M +upload_max_filesize=5M +realpath_cache_size=4096K +realpath_cache_ttl=600 + +date.timezone=${PHP_DATE_TIMEZONE} diff --git a/OpenMarketplace/docker/test.sh b/OpenMarketplace/docker/test.sh new file mode 100755 index 0000000..29dddcb --- /dev/null +++ b/OpenMarketplace/docker/test.sh @@ -0,0 +1,24 @@ +#!/bin/sh +set -e + +readonly timeout=100 +readonly sleep_time=5 + +i=1 +time=$((timeout * sleep_time)) + +until curl -L --fail http://localhost:80 2>/dev/null +do + i=$((i+1)) + + if [ "${i}" -gt "${timeout}" ]; then + + echo "Sylius Store was never created, aborting due to ${time}s timeout!" + curl -L http://localhost:80 -H Accept:application/json + exit 1 + else + echo "Sylius Store did not response" + fi + + sleep $sleep_time +done diff --git a/OpenMarketplace/ecs.php b/OpenMarketplace/ecs.php new file mode 100644 index 0000000..838a547 --- /dev/null +++ b/OpenMarketplace/ecs.php @@ -0,0 +1,20 @@ +import('vendor/bitbag/coding-standard/ecs.php'); + + $parameters = $containerConfigurator->parameters(); + $parameters->set(Option::PATHS, [ + __DIR__ . '/src', + __DIR__ . '/tests', + __DIR__ . '/spec', + ]); + $parameters->set(Option::SKIP, [ + __DIR__ . '/tests/Application/var', + ]); +}; diff --git a/OpenMarketplace/features/.gitkeep b/OpenMarketplace/features/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/OpenMarketplace/features/Conversation/admin_start_conversation.feature b/OpenMarketplace/features/Conversation/admin_start_conversation.feature new file mode 100644 index 0000000..7b22d51 --- /dev/null +++ b/OpenMarketplace/features/Conversation/admin_start_conversation.feature @@ -0,0 +1,105 @@ +@admin_start_conversation +Feature: Starting conversation by Administrator + In order to contact with Vendor + As an admin I want to sent message to a Vendor + + Background: + Given there is an administrator with name "admin" + And the store operates on a single channel in "United States" + And the store operates in "Poland" + And there is a vendor user "test@company.domain" registered in country "PL" + And vendor company name is "company" + And there is conversation category "test category" + + Scenario: AdminUser begins conversation + Given I am logged in as an administrator + And I am on "/admin" + And I follow "Messages" + And I follow "Create" + And I select "test category" from "mvm_conversation[category]" + And I fill in "Message" with "test Message" + And I select "company" from "mvm_conversation_vendorUser" + And I press "Submit" + Then I should see "test Message" + + Scenario: Vendor begins conversation + Given I am logged in as "test@company.domain" + And I am on "/en_US/account/vendor/conversation/create" + And I select "test category" from "mvm_conversation[category]" + And I fill in "Message" with "test Message" + And I press "Submit" + Then I should see "test Message" + + Scenario: AdminUser begins conversation, and Vendor checks if he received it + Given I am logged in as an administrator + And I am on "/admin" + And I follow "Messages" + And I follow "Create" + And I select "test category" from "mvm_conversation[category]" + And I fill in "Message" with "test Message" + And I select "company" from "mvm_conversation_vendorUser" + And I press "Submit" + And I am logged in as "test@company.domain" + And I am on "/en_US/account/vendor/conversations" + And I follow "Thread with" + Then I should see "test Message" + And I should see "test category" + + Scenario: AdminUser begins conversation, and Vendor writes back + Given I am logged in as an administrator + And I am on "/admin" + And I follow "Messages" + And I follow "Create" + And I select "test category" from "mvm_conversation[category]" + And I fill in "Message" with "test Message" + And I select "company" from "mvm_conversation_vendorUser" + And I press "Submit" + And I am logged in as "test@company.domain" + And I am on "/en_US/account/vendor/conversations" + And I follow "Thread with" + And I fill in "Message" with "second test Message" + And I press "Submit" + Then I should see "second test Message" + + Scenario: Other vendors cannot see conversation + Given I am logged in as an administrator + And I am on "/admin" + And I follow "Messages" + And I follow "Create" + And I fill in "Message" with "test Message" + And I select "company" from "mvm_conversation_vendorUser" + And I press "Submit" + And there is a vendor user "second@company.domain" registered in country "PL" + And I am logged in as "second@company.domain" + And I am on "/en_US/account/vendor/conversations" + Then I should see "You have no open threads" + + Scenario: Conversation must have category + Given I am logged in as "test@company.domain" + And I am on "/en_US/account/vendor/conversation/create" + And I fill in "Message" with "test Message" + And I press "Submit" + Then I should see "This value should not be blank." + + Scenario: Admin adds attachment to conversation + Given I am logged in as an administrator + And I am on "/admin/conversation/create" + And I select "test category" from "mvm_conversation[category]" + And I fill in "Message" with "test Message" + And I select "company" from "mvm_conversation_vendorUser" + And I attach the file "images/valid_logo.png" to "mvm_conversation_messages___name___file" + And I press "Submit" + Then I should see "test Message" + And I should see "Attachment: File" + + Scenario: Filling form with not allowed attachment + Given I am logged in as an administrator + And I am on "/admin/conversation/create" + And I select "test category" from "mvm_conversation[category]" + And I fill in "Message" with "test Message" + And I select "company" from "mvm_conversation_vendorUser" + And I attach the file "unsafe.html" to "mvm_conversation_messages___name___file" + And I press "Submit" + Then I should not see "test Message" + And I should not see "Attachment: File" + And I should see 1 "div.sylius-validation-error" elements diff --git a/OpenMarketplace/features/admin/accepting_product_listing.feature b/OpenMarketplace/features/admin/accepting_product_listing.feature new file mode 100644 index 0000000..98b9896 --- /dev/null +++ b/OpenMarketplace/features/admin/accepting_product_listing.feature @@ -0,0 +1,55 @@ +@managing_product_listings +Feature: Verifying product listing + In order to create new product + As an Administrator + I need to be able to verify product listing + + Background: + Given there is an admin user "admin" with password "admin" + And there is an vendor user "vendor" with password "vendor" + And the store operates on a channel named "Web-US" in "USD" currency + And I am logged in as an admin + + @ui + Scenario: Accept product listing + Given there is 1 product listing + And I am on "/admin" + And I follow "Product listings" + And I should see 1 product listing + And I should see product's listing status "Under verification" + And I follow "Details" + And I should see url "#\/admin\/product-listings\/(\d+)#" + When I click "Accept" button + Then I should see url "#\/admin\/product-listings\/$#" + And I should see product's listing status "Accepted" + And I should see "Product listing accepted." + + @ui + Scenario: Accept product listing with channel + Given there is product listing enabled for channel + And I am on "/admin" + And I follow "Product listings" + And I should see 1 product listing + And I should see product's listing status "Under verification" + And I follow "Details" + And I should see url "#\/admin\/product-listings\/(\d+)#" + When I click "Accept" button + Then there should be product with channel enabled + + @ui + Scenario: Accept updated product listing with attributes + Given there is product listing enabled for channel + And there is a product 'green-jeans' attached to the product listing + And there is draft attribute with code 'attribute-1' and type 'text' + And there is draft attribute with code 'attribute-2' and type 'text' + And there is already published product with attribute 'attribute-1' with value 'value-1' + And product listing has attribute 'attribute-2' with value 'value-2' + When I am on "/admin" + And I follow "Product listings" + And I should see 1 product listing + And I should see product's listing status "Under verification" + And I follow "Details" + And I click "Accept" button + And I follow "Details" + Then I should see 'attribute-2' with value 'value-2' + And I should not see 'attribute-1' with value 'value-1' diff --git a/OpenMarketplace/features/admin/customer_orders.feature b/OpenMarketplace/features/admin/customer_orders.feature new file mode 100644 index 0000000..6312bee --- /dev/null +++ b/OpenMarketplace/features/admin/customer_orders.feature @@ -0,0 +1,26 @@ +@hiding_primary_orders_in_customer_tab +Feature: Hiding primary orders in customers tab + As an administrator + During orders list view for a specific customer + I cannot see primary orders + + Background: + Given I am logged in as an administrator + And the store has currency "EUR" + And the store has currency "GBP" + And the store operates on a channel named "Web-EU" in "EUR" currency and with hostname "web-eu" + And that channel allows to shop using "EUR" and "GBP" currencies + And the store has country "Ireland" + And the store has a product "Leprechaun's Gold" priced at "€10.00" in "Web-EU" channel + And the store has a zone "EU" + And the store has customer "example@user.com" + And the store has "UPS" shipping method with "$20.00" fee per unit for "Web-EU" channel + And the store has also a payment method "Bank transfer" with a code "transfer" + And store has primary and secondary order with payment state "paid" + + @ui + Scenario: Viewing sales summary + Given I am on "/admin" + And I follow "Customers" + And I follow "Show orders" + Then I should see 1 orders diff --git a/OpenMarketplace/features/admin/dashboard_statistics.feature b/OpenMarketplace/features/admin/dashboard_statistics.feature new file mode 100644 index 0000000..3222a30 --- /dev/null +++ b/OpenMarketplace/features/admin/dashboard_statistics.feature @@ -0,0 +1,24 @@ +@dashboard_statistics +Feature: Viewing dashboard statistics + As admin user in dashboard panel + I want to see only statistics correlated with + secondary orders + + Background: + Given I am logged in as an administrator + And the store has currency "EUR" + And the store has currency "GBP" + And the store operates on a channel named "Web-EU" in "EUR" currency and with hostname "web-eu" + And that channel allows to shop using "EUR" and "GBP" currencies + And the store has country "Ireland" + And the store has a product "Leprechaun's Gold" priced at "€10.00" in "Web-EU" channel + And the store has a zone "EU" + And the store has customer "example@user.com" + And the store has "UPS" shipping method with "$20.00" fee per unit for "Web-EU" channel + And the store has also a payment method "Bank transfer" with a code "transfer" + And store has primary and secondary order with payment state "paid" + + @ui + Scenario: Viewing sales summary + Given I am on "/admin" + Then statistics should omit primary order diff --git a/OpenMarketplace/features/admin/editing_vendors.feature b/OpenMarketplace/features/admin/editing_vendors.feature new file mode 100644 index 0000000..7ec2b98 --- /dev/null +++ b/OpenMarketplace/features/admin/editing_vendors.feature @@ -0,0 +1,47 @@ +@editing_vendors +Feature: Editing Vendors + In order to edit a Vendor + As an Administrator + When Vendor should be verified + Then I should be able to see Vendor edit page + + Background: + Given I am logged in as an administrator + And I am on "/admin" + + @ui + Scenario: Editing verified Vendor who requested change of profile information + Given There is a "verified" Vendor who "requested" change + When I follow "Vendors" + And I follow "Edit" + And I fill in "vendor_vendorAddress_city" with "Zgorzelec" + And I fill in "vendor_vendorAddress_postalCode" with "59-900" + And I fill in "vendor_vendorAddress_street" with "Grove street" + And I press "Save changes" + Then I should see "Vendor has been successfully updated." + + @ui + Scenario: Editing verified vendors which did not requested change of profile + Given There is a "verified" Vendor who "did not requested" change + When I follow "Vendors" + And I follow "Edit" + And I fill in "vendor_vendorAddress_city" with "Zgorzelec" + And I fill in "vendor_vendorAddress_postalCode" with "59-900" + And I fill in "vendor_vendorAddress_street" with "Grove street" + And I press "Save changes" + Then I should see "Vendor has been successfully updated." + + @ui + Scenario: Editing unverified vendors which requested change of profile + Given There is a "unverified" Vendor who "requested" change + When I follow "Vendors" + And I should not see "Edit" + + @ui + Scenario: Editing unverified vendors which did not requested change of profile + Given There is a "unverified" Vendor who "did not requested" change + When I follow "Vendors" + And I should not see "Edit" + + + diff --git a/OpenMarketplace/features/admin/listing_product_listing.feature b/OpenMarketplace/features/admin/listing_product_listing.feature new file mode 100644 index 0000000..83da5d0 --- /dev/null +++ b/OpenMarketplace/features/admin/listing_product_listing.feature @@ -0,0 +1,18 @@ +@managing_product_listings +Feature: Listing product listings + In order to verify product listing + As an Administrator + I need to be able to see product listings list + + Background: + Given there is an admin user "admin" with password "admin" + And there is an vendor user "vendor" with password "vendor" + And I am logged in as an admin + And the store operates on a single channel + + @ui + Scenario: Listing product listings + Given there are 3 product listings + And I am on "/admin" + When I follow "Product listings" + Then I should see 3 product listings diff --git a/OpenMarketplace/features/admin/managing_settlements_frequency.feature b/OpenMarketplace/features/admin/managing_settlements_frequency.feature new file mode 100644 index 0000000..8a04be4 --- /dev/null +++ b/OpenMarketplace/features/admin/managing_settlements_frequency.feature @@ -0,0 +1,89 @@ +@admin_settlements_frequency +Feature: Admin can manage settlements frequency + In order to settle vendors' settlements + As an Admin + I want to be able to change settlement frequency and to see compensatory settlements + + Background: + Given there is an admin user "admin" with password "admin" + And I am logged in as an administrator + And there is a "verified" vendor user "bruce@domain.io" registered in country with code "PL" named "Bruce" + And vendor "bruce@domain.io" was created on "2022-11-11 00:00:00" + And the store operates on a channel named "Web-US" in "USD" currency + And the store operates on a channel named "Web-EU" in "USD" currency + And the store has a product "Leprechaun's Gold" priced at "$10.00" in "Web-US" channel + And the store has a product "Unicorn horn" priced at "$10.00" in "Web-EU" channel + And vendor "bruce@domain.io" has an order with number "US-BRUCE-1" priced at "$20.00" in channel "Web-US" + And vendor "bruce@domain.io" has an order with number "EU-BRUCE-1" priced at "$100.00" in channel "Web-EU" + + @ui + Scenario: Admin can generate compensatory settlement frequency when changing from cyclical to non-cyclical + Given vendor "bruce@domain.io" has "Weekly" settlement frequency + And order "US-BRUCE-1" has been included in previously generated settlement + And order "EU-BRUCE-1" has been paid in current settlement cycle + And I am on admin vendor listing page + When I click edit button for "Bruce" + And I set settlement frequency to "Virtual wallet" + And I submit vendor update form + And I visit the admin settlements page + Then I should see 2 settlement for vendor "Bruce" + And I should see 1 settlement with today as end of settlement period + And I should see 1 settlement with different day as end of settlement period + + @ui + Scenario: Admin can generate compensatory settlement frequency when changing from non-cyclical to cyclical + Given there is a virtual wallet for vendor "bruce@domain.io" and channel "Web-US" with balance "100.92" + And there is a virtual wallet for vendor "bruce@domain.io" and channel "Web-EU" with balance "59.72" + And vendor "bruce@domain.io" has "Virtual wallet" settlement frequency + And I am on admin vendor listing page + When I click edit button for "Bruce" + And I set settlement frequency to "Weekly" + And I submit vendor update form + And I visit the admin settlements page + And I filter settlements by vendor "Bruce" + Then I should see 2 settlement for vendor "Bruce" + And I should see settlement total with amount of "100.92" for "Web-US" channel + And I should see settlement total with amount of "59.72" for "Web-EU" channel + + @ui + Scenario: Admin can clear virtual wallets when changing from non-cyclical to cyclical + Given there is a virtual wallet for vendor "bruce@domain.io" and channel "Web-US" with balance "100.92" + Given there is a virtual wallet for vendor "bruce@domain.io" and channel "Web-EU" with balance "59.72" + And vendor "bruce@domain.io" has "Virtual wallet" settlement frequency + And I am on admin vendor listing page + When I click edit button for "Bruce" + And I set settlement frequency to "Weekly" + And I submit vendor update form + And I visit the admin settlements page + And I filter settlements by vendor "Bruce" + Then I visit the admin virtual wallets page + And I filter virtual wallets by vendor "Bruce" + And I should see 2 virtual wallets + And I should see "0.00" as balance for "Web-US" channel + And I should see "0.00" as balance for "Web-EU" channel + + @ui + Scenario: Admin can generate compensatory settlement when changing from longer to shorter settlement frequency + Given vendor "bruce@domain.io" has "Monthly" settlement frequency + And order "EU-BRUCE-1" has been paid at the beginning of current settlement cycle + And I am on admin vendor listing page + When I click edit button for "Bruce" + And I set settlement frequency to "Weekly" + And I submit vendor update form + And I visit the admin settlements page + Then I should see 1 settlement for vendor "Bruce" + And I should see 1 settlement with today as end of settlement period + And I should see settlement total with amount of "100.00" for "Web-EU" channel + + @ui + Scenario: Admin can generate compensatory settlement when changing from shorter to longer settlement frequency + Given vendor "bruce@domain.io" has "Weekly" settlement frequency + And order "EU-BRUCE-1" has been paid at the beginning of current settlement cycle + And I am on admin vendor listing page + When I click edit button for "Bruce" + And I set settlement frequency to "Monthly" + And I submit vendor update form + And I visit the admin settlements page + Then I should see 1 settlement for vendor "Bruce" + And I should see 1 settlement with today as end of settlement period + And I should see settlement total with amount of "100.00" for "Web-EU" channel diff --git a/OpenMarketplace/features/admin/managing_vendors.feature b/OpenMarketplace/features/admin/managing_vendors.feature new file mode 100644 index 0000000..1e711fd --- /dev/null +++ b/OpenMarketplace/features/admin/managing_vendors.feature @@ -0,0 +1,27 @@ +@managing_vendors +Feature: Listing vendors + In order to manage vendors + As an Administrator + I should be able to see vendors list + + Background: + Given There is an admin user "admin" with password "admin" + And I am logged in as an admin + + @ui + Scenario: Listing vendors + Given There are 5 vendors listed + And I am on "/admin" + When I follow "Vendors" + Then I should see 5 vendor rows + + @ui + Scenario: Vendor details page has link to associated customer + Given there is an vendor user "vendor" with password "password" + And I am on "/admin" + And I follow "Vendors" + And I follow "Details" + Then I should see "Shop user" + And page should contain valid customer "vendor@email.com" link + And I should see vendors commission data + And I should see settlement frequency "Weekly" diff --git a/OpenMarketplace/features/admin/message_categories.feature b/OpenMarketplace/features/admin/message_categories.feature new file mode 100644 index 0000000..75f58dd --- /dev/null +++ b/OpenMarketplace/features/admin/message_categories.feature @@ -0,0 +1,28 @@ +@messaging +Feature: Verifying validation of message category + In order to create new message category + As an Administrator + I need to be able to validate message category + + Background: + Given there is an administrator with name "admin" + And there is conversation category "test category" + + @ui + Scenario: Incorrect message category name + Given I am logged in as an administrator + When I am on "/admin" + And I follow "Message categories" + And I follow "Create" + And I fill in "Name" with "" + And I press "Create" + Then I should see "This value should not be blank." + + Scenario: Administrator begins conversation + Given I am logged in as an administrator + When I am on "/admin" + And I follow "Message categories" + And I follow "Edit" + And I fill in "Name" with "" + And I press "Save changes" + Then I should see "This value should not be blank." diff --git a/OpenMarketplace/features/admin/order_viewing.feature b/OpenMarketplace/features/admin/order_viewing.feature new file mode 100644 index 0000000..9bac111 --- /dev/null +++ b/OpenMarketplace/features/admin/order_viewing.feature @@ -0,0 +1,25 @@ +@order_viewing +Feature: Hiding primary orders in order list view + As an administrator + During orders list view + I cannot see primary orders + + Background: + Given I am logged in as an administrator + And the store has currency "EUR" + And the store has currency "GBP" + And the store operates on a channel named "Web-EU" in "EUR" currency and with hostname "web-eu" + And that channel allows to shop using "EUR" and "GBP" currencies + And the store has country "Ireland" + And the store has a product "Leprechaun's Gold" priced at "€10.00" in "Web-EU" channel + And the store has a zone "EU" + And the store has customer "example@user.com" + And the store has "UPS" shipping method with "$20.00" fee per unit for "Web-EU" channel + And the store has also a payment method "Bank transfer" with a code "transfer" + And store has primary and secondary order with payment state "paid" + + @ui + Scenario: Viewing sales summary + Given I am on "/admin" + And I follow "Orders" + Then I should see 1 secondary order diff --git a/OpenMarketplace/features/admin/payment_viewing.feature b/OpenMarketplace/features/admin/payment_viewing.feature new file mode 100644 index 0000000..c3afe90 --- /dev/null +++ b/OpenMarketplace/features/admin/payment_viewing.feature @@ -0,0 +1,24 @@ +@payment_viewing +Feature: Login in to admin panel + and going to payments tab + I should not see primary order payments + + Background: + Given the store has currency "EUR" + And the store has currency "GBP" + And the store operates on a channel named "Web-EU" in "EUR" currency and with hostname "web-eu" + And that channel allows to shop using "EUR" and "GBP" currencies + And the store has country "Ireland" + And the store has a product "Leprechaun's Gold" priced at "€10.00" in "Web-EU" channel + And the store has a zone "EU" + And the store has customer "example@user.com" + And the store has "UPS" shipping method with "$20.00" fee per unit for "Web-EU" channel + And the store has also a payment method "Bank transfer" with a code "transfer" + + + @ui + Scenario: Browsing payments tab on panel admin + Given I am logged in as an administrator + And store has primary and secondary order + And I am on "/admin/payments/" + Then I should see 1 payment for secondary order diff --git a/OpenMarketplace/features/admin/product_listing_details.feature b/OpenMarketplace/features/admin/product_listing_details.feature new file mode 100644 index 0000000..b448c9b --- /dev/null +++ b/OpenMarketplace/features/admin/product_listing_details.feature @@ -0,0 +1,25 @@ +@managing_product_listings +Feature: Product listing details + In order to verify product listing + As an Administrator + I need to be able to see the details of the product listing + + Background: + Given there is an admin user "admin" with password "admin" + And the store operates on a single channel in "United States" + And there is an vendor user "vendor" with password "vendor" + And the store operates on a channel named "Web-US" in "USD" currency + And I am logged in as an admin + + @ui + Scenario: Going to product listing details page + Given There is attribute with code "test_attribute" + And There is a product listing with code "product-listing-code" and name "product-listing-name" and status "under_verification" with attribute and image + And I am on "/admin" + And I follow "Product listings" + And I should see 1 product listing + When I follow "Details" + Then I should see url "#\/admin\/product-listings\/(\d+)#" + And I should see "product-listing-description" + And I should see "attribute_testing_value" + And I should see image diff --git a/OpenMarketplace/features/admin/product_pricing.feature b/OpenMarketplace/features/admin/product_pricing.feature new file mode 100644 index 0000000..8b155fb --- /dev/null +++ b/OpenMarketplace/features/admin/product_pricing.feature @@ -0,0 +1,28 @@ +@product_pricing +Feature: Product pricing + As an Administrator + I need to be able to set product price + + Background: + And the store operates on a single channel in "United States" + And the store operates on a channel named "Web-US" in "USD" currency + + @ui + Scenario: Setting wrong value as price + Given I am logged in as an administrator + And the store has a product "testproduct" + And I am on "/admin/products/" + And I follow "Edit" + And I fill in "sylius_product[variant][channelPricings][web_us][price]" with "222222222222222222222222" + And I click "Save changes" + Then I should see "This value is not valid." + + @ui + Scenario: Setting correct value as price + Given I am logged in as an administrator + And the store has a product "testproduct" + And I am on "/admin/products/" + And I follow "Edit" + And I fill in "sylius_product[variant][channelPricings][web_us][price]" with "222222" + And I click "Save changes" + Then I should see "Success" diff --git a/OpenMarketplace/features/admin/rejecting_product_listing.feature b/OpenMarketplace/features/admin/rejecting_product_listing.feature new file mode 100644 index 0000000..c618610 --- /dev/null +++ b/OpenMarketplace/features/admin/rejecting_product_listing.feature @@ -0,0 +1,31 @@ +@managing_product_listings +Feature: Rejecting product listing + As an Administrator + I need to be able to reject product listing + + Background: + Given there is an admin user "admin" with password "admin" + And the store operates on a channel named "Web-US" in "USD" currency + And there is an vendor user "vendor" with password "vendor" + And I am logged in as an admin + And there is a vendor user "test@company.domain" registered in country "PL" + And there is conversation category "test category" + + + @ui + Scenario: Reject product listing creates conversation + Given there is 1 product listing created by vendor + And I am on "/admin" + And I follow "Product listings" + And I should see 1 product listing + And I should see product's listing status "Under verification" + And I follow "Details" + And I should see url "#\/admin\/product-listings\/(\d+)#" + And I select "test category" from "mvm_conversation[category]" + And I fill in "mvm_conversation[messages][__name__][content]" with "reason to reject" + And I click "Reject" button + Then I should see url "#\/admin\/product-listings\/$#" + And I should see product's listing status "Rejected" + And I am logged in as an user "test@company.domain" with password "password" + And I am on "/en_US/account/vendor/conversations" + And I should see "reason to reject" diff --git a/OpenMarketplace/features/admin/restoring_product.feature b/OpenMarketplace/features/admin/restoring_product.feature new file mode 100644 index 0000000..a20b77f --- /dev/null +++ b/OpenMarketplace/features/admin/restoring_product.feature @@ -0,0 +1,19 @@ +@product_removal_admin +Feature: Restoring product listing visibility + As a administrator i can restore product listing removing by vendor + + Background: + Given there is an admin user "admin" with password "admin" + And there is an vendor user "vendor" with password "vendor" + And I am logged in as an admin + And there is a vendor user "test@company.domain" registered in country "PL" + And the store operates on a channel named "Web-US" in "USD" currency + + @ui + Scenario: Restoring visibility of product listing + Given there is 1 product listing created by vendor + And This product listing visibility is removed + And I follow "Product listings" + Then I should see "Restore" + And I click "Restore" + Then I should not see "Restore" diff --git a/OpenMarketplace/features/admin/settlements.feature b/OpenMarketplace/features/admin/settlements.feature new file mode 100644 index 0000000..61186ca --- /dev/null +++ b/OpenMarketplace/features/admin/settlements.feature @@ -0,0 +1,66 @@ + @admin_settlements + Feature: Admin can manage settlements + In order to settle vendors' settlements + As an Admin + I want to visit settlements page and filter them + + Background: + Given there is an admin user "admin" with password "admin" + And I am logged in as an administrator + And there is a "verified" vendor user "bruce@domain.io" registered in country with code "PL" named "Bruce" + And there is a "verified" vendor user "secondary@example.io" registered in country with code "PL" named "Secondary" + And the store operates on a channel named "Web-US" in "USD" currency + And the store operates on a channel named "Web-PL" in "PLN" currency + + @ui + Scenario: Admin can see settlements of all vendors + Given there is a "new" settlement for vendor "bruce@domain.io" + And there is a "accepted" settlement for vendor "bruce@domain.io" + And there is a "settled" settlement for vendor "bruce@domain.io" + And there is a "new" settlement for vendor "secondary@example.io" + And there is a "accepted" settlement for vendor "secondary@example.io" + And there is a "settled" settlement for vendor "secondary@example.io" + When I visit the admin settlements page + Then I should see 6 settlements + + @ui + Scenario: Admin can filter settlements by status + Given there is a "new" settlement for vendor "bruce@domain.io" + And there is a "accepted" settlement for vendor "bruce@domain.io" + And there is a "settled" settlement for vendor "bruce@domain.io" + When I visit the admin settlements page + And I filter settlements by status "New" + Then I should see 1 settlements + + @ui + Scenario: Admin can filter settlements by period + Given there is a "new" settlement for vendor "bruce@domain.io" + And there is a "accepted" settlement for vendor "secondary@example.io" + When I visit the admin settlements page + And I filter settlements by vendor "Bruce" + Then I should see 1 settlements + + @ui + Scenario: Admin can filter settlements by channel + Given there is a settlement for channel "Web-US" + And there is a settlement for channel "Web-PL" + When I visit the admin settlements page + And I filter settlements by channel "Web-PL" + Then I should see 1 settlements + + @ui + Scenario: Admin can sort settlements by channel + Given there is a settlement for channel "Web-US" + And there is a settlement for channel "Web-PL" + When I visit the admin settlements page + And I sort the list by "channel" in "ascending" order + Then I should see settlement for channel "Web-PL" first + + @ui + Scenario: Admin can clear filters on setllement page + Given there is a "new" settlement for vendor "bruce@domain.io" + And there is a "accepted" settlement for vendor "secondary@example.io" + When I visit the admin settlements page + And I filter settlements by vendor "Bruce" + And I clear settlement filters + Then I should see 2 settlements diff --git a/OpenMarketplace/features/admin/shipment_viewing.feature b/OpenMarketplace/features/admin/shipment_viewing.feature new file mode 100644 index 0000000..93100ce --- /dev/null +++ b/OpenMarketplace/features/admin/shipment_viewing.feature @@ -0,0 +1,24 @@ +@shipment_viewing +Feature: Login in to admin panel + and going to payments tab + i should not see primary order payments + + Background: + Given the store has currency "EUR" + And the store has currency "GBP" + And the store operates on a channel named "Web-EU" in "EUR" currency and with hostname "web-eu" + And that channel allows to shop using "EUR" and "GBP" currencies + And the store has country "Ireland" + And the store has a product "Leprechaun's Gold" priced at "€10.00" in "Web-EU" channel + And the store has a zone "EU" + And the store has customer "example@user.com" + And the store has "UPS" shipping method with "$20.00" fee per unit for "Web-EU" channel + And the store has also a payment method "Bank transfer" with a code "transfer" + + + @ui + Scenario: Browsing shipments tab on panel admin + Given I am logged in as an administrator + And store has primary and secondary order + And I am on "/admin/shipments/" + Then I should see 1 shipment for secondary order diff --git a/OpenMarketplace/features/admin/verifying_vendors.feature b/OpenMarketplace/features/admin/verifying_vendors.feature new file mode 100644 index 0000000..3ffb18b --- /dev/null +++ b/OpenMarketplace/features/admin/verifying_vendors.feature @@ -0,0 +1,15 @@ +@verifying_vendors +Feature: Verifying Vendors account + In order to verify a vendor + As an Administrator + I should be able to see Vendor details page + + @ui + Scenario: Verifying vendors + Given I am logged in as an administrator + And I am on "/admin" + And There is an unverified Vendor + When I follow "Vendors" + And I follow "Details" + And I click "Verify" + Then I should see "Vendor has been successfully verified" diff --git a/OpenMarketplace/features/admin/virtual_wallet.feature b/OpenMarketplace/features/admin/virtual_wallet.feature new file mode 100644 index 0000000..7abf135 --- /dev/null +++ b/OpenMarketplace/features/admin/virtual_wallet.feature @@ -0,0 +1,74 @@ + @admin_virtual_wallets + Feature: Admin can view virtual wallets + In order to be able to manage virtual wallets + As an Admin + I want to visit virtual wallets page and filter them + + Background: + Given there is an admin user "admin" with password "admin" + And I am logged in as an administrator + And there is a "verified" vendor user "bruce@domain.io" registered in country with code "PL" named "Bruce" + And there is a "verified" vendor user "secondary@example.io" registered in country with code "PL" named "Secondary" + And the store operates on a channel named "Web-US" in "USD" currency + And the store operates on a channel named "Web-EU" in "USD" currency + And the store has a product "Leprechaun's Gold" priced at "$10.00" in "Web-US" channel + And the store has a product "Unicorn horn" priced at "$10.00" in "Web-EU" channel + + @ui + Scenario: Admin can see virtual wallets of all vendors + Given there is a virtual wallet for vendor "bruce@domain.io" and channel "Web-US" with balance "100.92" + And there is a virtual wallet for vendor "bruce@domain.io" and channel "Web-EU" with balance "17.35" + And there is a virtual wallet for vendor "secondary@example.io" and channel "Web-US" with balance "75.19" + And there is a virtual wallet for vendor "secondary@example.io" and channel "Web-EU" with balance "14.27" + When I visit the admin virtual wallets page + Then I should see 4 virtual wallets + + @ui + Scenario: Admin can filter virtual wallets by vendor + Given there is a virtual wallet for vendor "bruce@domain.io" and channel "Web-EU" with balance "17.35" + And there is a virtual wallet for vendor "secondary@example.io" and channel "Web-US" with balance "75.19" + When I visit the admin virtual wallets page + And I filter virtual wallets by vendor "Bruce" + Then I should see 1 virtual wallets + + @ui + Scenario: Admin can filter virtual wallets by channel + Given there is a virtual wallet for vendor "bruce@domain.io" and channel "Web-EU" with balance "17.35" + And there is a virtual wallet for vendor "secondary@example.io" and channel "Web-EU" with balance "43.38" + And there is a virtual wallet for vendor "bruce@domain.io" and channel "Web-US" with balance "75.19" + When I visit the admin virtual wallets page + And I filter virtual wallets by channel "Web-EU" + Then I should see 2 virtual wallets + + @ui + Scenario: Admin can sort virtual wallets by channel + Given there is a virtual wallet for vendor "bruce@domain.io" and channel "Web-EU" with balance "17.35" + And there is a virtual wallet for vendor "secondary@example.io" and channel "Web-US" with balance "75.19" + When I visit the admin virtual wallets page + And I sort the list by "channel" in "descending" order + Then I should see virtual wallet for channel "Web-US" first + + @ui + Scenario: Admin can sort virtual wallets by vendor + Given there is a virtual wallet for vendor "bruce@domain.io" and channel "Web-EU" with balance "17.35" + And there is a virtual wallet for vendor "secondary@example.io" and channel "Web-US" with balance "75.19" + When I visit the admin virtual wallets page + And I sort the list by "vendor" in "ascending" order + Then I should see virtual wallet for vendor "Bruce" first + + @ui + Scenario: Admin can sort virtual wallets by balance + Given there is a virtual wallet for vendor "bruce@domain.io" and channel "Web-EU" with balance "17.35" + And there is a virtual wallet for vendor "secondary@example.io" and channel "Web-US" with balance "75.19" + When I visit the admin virtual wallets page + And I sort the list by "balance" in "ascending" order + Then I should see virtual wallet for vendor "Bruce" first + + @ui + Scenario: Admin can clear filters on virtual wallets page + Given there is a virtual wallet for vendor "bruce@domain.io" and channel "Web-EU" with balance "17.35" + And there is a virtual wallet for vendor "secondary@example.io" and channel "Web-US" with balance "75.19" + When I visit the admin virtual wallets page + And I filter virtual wallets by vendor "Bruce" + And I clear virtual wallets filters + Then I should see 2 virtual wallets diff --git a/OpenMarketplace/features/shop/account/order/pay_from_details_page.feature b/OpenMarketplace/features/shop/account/order/pay_from_details_page.feature new file mode 100644 index 0000000..4534a61 --- /dev/null +++ b/OpenMarketplace/features/shop/account/order/pay_from_details_page.feature @@ -0,0 +1,22 @@ +@shop_account_order +Feature: Pay from order details page + In order to pay for order + As a customer + I want to be able to pay for primary order if I go to pay from order details page + + Background: + Given the store operates on a single channel in "United States" + And the store allows paying Offline + And the store allows shipping with "fedex" + And there is a customer "customer test" with an email "email@example.com" + And I am logged in as "email@example.com" + And store has 1 products from different Vendors + + @ui + Scenario: Pay + Given The customer "email@example.com" has new order + When I view the summary of my order "#000000001" + And I follow "Pay" + Then I should see "#000000001" in the "div.segment .header" element + And I should be on primary order payment page + diff --git a/OpenMarketplace/features/shop/order.feature b/OpenMarketplace/features/shop/order.feature new file mode 100644 index 0000000..80bc060 --- /dev/null +++ b/OpenMarketplace/features/shop/order.feature @@ -0,0 +1,185 @@ +@shop_order +Feature: Spliting orders when cart was filled with products from different Vendors + As a customer + I want to be able to buy products from multiple vendors + + Background: + Given the store operates on a single channel in "United States" + And there is a customer "customer test" with an email "email@example.com" + And I am a logged in customer with name "customer test" + + @ui + Scenario: Picking products from different Vendors + Given store has 5 products from different Vendors + And I have 3 products in cart + And I finalize order + And I am on "en_US/account/orders/" + Then I should see 3 orders + + @ui + Scenario: Picking products from same Vendor + Given store has 5 products from same Vendor + And I have 2 products in cart + And I finalize order + And I am on "en_US/account/orders/" + Then I should see 1 orders + + @ui + Scenario: Do not Assign number to primary order + Given store has 4 products from different Vendors + And I have 3 products in cart + And I finalize order + Then primary order should not have number + + + @ui + Scenario: Browsing orders, admin cannot see primary orders + Given store has 4 products from different Vendors + And I have 3 products in cart + And I finalize order + Given I am logged in as an administrator + And I am on "/admin" + And I follow "Orders" + Then I should see 3 secondary orders + + @ui + Scenario: Browsing orders history, customer cannot see primary orders + Given store has 4 products from different Vendors + And I have 3 products in cart + And I finalize order + And I am on "/" + And I follow "My account" + And I follow "Order history" + Then I should see 3 secondary orders in order history + + @ui + Scenario: Shipping method requires at least one unit matches, method should be visible scenario + Given the store has "Envelope type" shipping category + And the store ships everywhere with Envelope + And this shipping method requires at least one unit matches to "Envelope type" shipping category + And store has 2 products from same Vendor + And vendor uses this shipping method + And one of it belongs to "Envelope type" shipping category + And I have 2 products in cart + And I am on "/en_US/checkout/address" + And I fill in "sylius_checkout_address[billingAddress][firstName]" with "Test name" + And I fill in "sylius_checkout_address[billingAddress][lastName]" with "Test name" + And I fill in "sylius_checkout_address[billingAddress][company]" with "Test company" + And I fill in "sylius_checkout_address[billingAddress][street]" with "Test street" + And I select "United States" from "sylius_checkout_address[billingAddress][countryCode]" + And I fill in "sylius_checkout_address[billingAddress][city]" with "Test city" + And I fill in "sylius_checkout_address[billingAddress][postcode]" with "Test code" + And I submit form + Then I should see "Envelope" + + @ui + Scenario: Shipping method requires at least one unit matches, method should not be visible scenario + Given the store has "Envelope type" shipping category + And the store ships everywhere with Envelope + And this shipping method requires at least one unit matches to "Envelope type" shipping category + And store has 2 products from same Vendor + And vendor uses this shipping method + And I have 2 products in cart + And I am on "/en_US/checkout/address" + And I fill in "sylius_checkout_address[billingAddress][firstName]" with "Test name" + And I fill in "sylius_checkout_address[billingAddress][lastName]" with "Test name" + And I fill in "sylius_checkout_address[billingAddress][company]" with "Test company" + And I fill in "sylius_checkout_address[billingAddress][street]" with "Test street" + And I select "United States" from "sylius_checkout_address[billingAddress][countryCode]" + And I fill in "sylius_checkout_address[billingAddress][city]" with "Test city" + And I fill in "sylius_checkout_address[billingAddress][postcode]" with "Test code" + And I submit form + Then I should see "There are currently no shipping methods available for your shipping address." + + @ui + Scenario: Shipping method requires all unit matches, method should be visible scenario + Given the store has "Envelope type" shipping category + And the store ships everywhere with Envelope + And this shipping method requires that all units match to "Envelope type" shipping category + And store has 1 products from same Vendor + And vendor uses this shipping method + And one of it belongs to "Envelope type" shipping category + And I have 1 products in cart + And I am on "/en_US/checkout/address" + And I fill in "sylius_checkout_address[billingAddress][firstName]" with "Test name" + And I fill in "sylius_checkout_address[billingAddress][lastName]" with "Test name" + And I fill in "sylius_checkout_address[billingAddress][company]" with "Test company" + And I fill in "sylius_checkout_address[billingAddress][street]" with "Test street" + And I select "United States" from "sylius_checkout_address[billingAddress][countryCode]" + And I fill in "sylius_checkout_address[billingAddress][city]" with "Test city" + And I fill in "sylius_checkout_address[billingAddress][postcode]" with "Test code" + And I submit form + Then I should see "Envelope" + + @ui + Scenario: Shipping method requires all unit matches, method should not be visible scenario + Given the store has "Envelope type" shipping category + And the store ships everywhere with Envelope + And this shipping method requires that all units match to "Envelope type" shipping category + And store has 2 products from same Vendor + And vendor uses this shipping method + And one of it belongs to "Envelope type" shipping category + And I have 2 products in cart + And I am on "/en_US/checkout/address" + And I fill in "sylius_checkout_address[billingAddress][firstName]" with "Test name" + And I fill in "sylius_checkout_address[billingAddress][lastName]" with "Test name" + And I fill in "sylius_checkout_address[billingAddress][company]" with "Test company" + And I fill in "sylius_checkout_address[billingAddress][street]" with "Test street" + And I select "United States" from "sylius_checkout_address[billingAddress][countryCode]" + And I fill in "sylius_checkout_address[billingAddress][city]" with "Test city" + And I fill in "sylius_checkout_address[billingAddress][postcode]" with "Test code" + And I submit form + Then I should see "There are currently no shipping methods available for your shipping address." + + @ui + Scenario: Shipping method requires none unit matches, method should not be visible scenario + Given the store has "Envelope type" shipping category + And the store ships everywhere with Envelope + And this shipping method requires that no units match to "Envelope type" shipping category + And store has 2 products from same Vendor + And vendor uses this shipping method + And one of it belongs to "Envelope type" shipping category + And I have 2 products in cart + And I am on "/en_US/checkout/address" + And I fill in "sylius_checkout_address[billingAddress][firstName]" with "Test name" + And I fill in "sylius_checkout_address[billingAddress][lastName]" with "Test name" + And I fill in "sylius_checkout_address[billingAddress][company]" with "Test company" + And I fill in "sylius_checkout_address[billingAddress][street]" with "Test street" + And I select "United States" from "sylius_checkout_address[billingAddress][countryCode]" + And I fill in "sylius_checkout_address[billingAddress][city]" with "Test city" + And I fill in "sylius_checkout_address[billingAddress][postcode]" with "Test code" + And I submit form + Then I should see "There are currently no shipping methods available for your shipping address." + + @ui + Scenario: Shipping method none unit matches, method should be visible scenario + Given the store has "Envelope type" shipping category + And the store ships everywhere with Envelope + And this shipping method requires that no units match to "Envelope type" shipping category + And store has 2 products from same Vendor + And vendor uses this shipping method + And I have 2 products in cart + And I am on "/en_US/checkout/address" + And I fill in "sylius_checkout_address[billingAddress][firstName]" with "Test name" + And I fill in "sylius_checkout_address[billingAddress][lastName]" with "Test name" + And I fill in "sylius_checkout_address[billingAddress][company]" with "Test company" + And I fill in "sylius_checkout_address[billingAddress][street]" with "Test street" + And I select "United States" from "sylius_checkout_address[billingAddress][countryCode]" + And I fill in "sylius_checkout_address[billingAddress][city]" with "Test city" + And I fill in "sylius_checkout_address[billingAddress][postcode]" with "Test code" + And I submit form + Then I should see "Envelope" + + @ui + Scenario: Browsing orders history, can see selected payment method + Given store has 1 products from same Vendor + And store has payment method "Cash on delivery" with code "cash_on_delivery" + And store has payment method "Bank transfer" with code "bank_transfer" + And I have 1 products in cart + When I finalize order with payment method "bank_transfer" + And I am on "/" + And I follow "My account" + And I follow "Order history" + And I should see 1 orders + And I follow "Show" button + Then I should see "Bank transfer" payment method diff --git a/OpenMarketplace/features/shop/vendor_page.feature b/OpenMarketplace/features/shop/vendor_page.feature new file mode 100644 index 0000000..6e50ddb --- /dev/null +++ b/OpenMarketplace/features/shop/vendor_page.feature @@ -0,0 +1,42 @@ +@vendor_page +Feature: Displaying vendor page + As a customer + I want to be able to visit vendor page + + Background: + Given the store operates on a single channel in "United States" + + @ui + Scenario: Viewing vendor products + Given store has 5 products from same vendor + Then I should see "5" products in the list + + @ui + Scenario: Paginating vendor products + Given store has 3 products from same vendor + And Pagination is set to display "2" orders per page + Then I should see 2 products on page "1" + And I should see 1 products on page "2" + + @ui + Scenario: Displaying only current vendor products + Given store has 5 products from different Vendors + And I should see 1 products on page "1" + + @ui + Scenario: Sorting vendor products + Given store has 3 products from same vendor + And sorting is set to "price" "ascending" + Then i should see products sorted by "price" + + @ui + Scenario: Searching for products + Given store has 3 products from same vendor + And product has name "test_name" + Then I should see 1 products when search for "test_name" + + @ui + Scenario: Viewing products from given taxon + Given store has 3 products from same vendor + And product belongs to "test" taxon + Then I should see 1 products on "test" taxon page diff --git a/OpenMarketplace/features/vendor/clients_listing.feature b/OpenMarketplace/features/vendor/clients_listing.feature new file mode 100644 index 0000000..67c9319 --- /dev/null +++ b/OpenMarketplace/features/vendor/clients_listing.feature @@ -0,0 +1,24 @@ +@clients_listing +Feature: Vendor can view his clients + In order to view clients + As a Vendor I want to visit page + + Background: + Given the store operates on a single channel in "United States" + And the store operates in "Poland" + And there is a "verified" vendor user "test@company.domain" registered in country "PL" + And I am logged in as "test@company.domain" + + @ui + Scenario: Listing a customer who made order with Vendor + Given There is order with property "state" with value "new" made with logged in seller + And The order is made by customer with first name "TestingClient" + And I am on customers page + Then I should see customer with name "TestingClient" + + @ui + Scenario: Not listing customers who placed an order with other vendors + Given There is order with property "state" with value "new" made with other seller + And The order is made by customer with first name "TestingClient" + And I am on customers page + Then I should not see customer with name "TestingClient" diff --git a/OpenMarketplace/features/vendor/create_product_listing.feature b/OpenMarketplace/features/vendor/create_product_listing.feature new file mode 100644 index 0000000..b565f60 --- /dev/null +++ b/OpenMarketplace/features/vendor/create_product_listing.feature @@ -0,0 +1,43 @@ +@vendor_managing_product_listings +Feature:Creating a product listing. + As a vendor, I need to be able + to create a product. + + Background: + Given there is an "verified" vendor user "vendor" with password "vendor" + And I am logged in as "vendor@email.com" + And the store operates on a channel named "Web-US" in "USD" currency + + @ui + Scenario: Creating product listing + When I am on a dashboard page + And I follow "Product listings" + And I follow "Create Product listing" + And I fill form with non unique code + And I click "Save" button + Then I should see product's listing status "Created" + And I should see "Product listing created." + + @ui + Scenario: Creating product listing with non unique code + Given there is 1 product listing created by vendor with status "verified" + When I am on a dashboard page + And I follow "Product listings" + And I follow "Create Product listing" + And I fill form with non unique code + And I click "Save" button + Then I should see non unique code error message + + @ui + Scenario: Creating product listing without description + When I am on a dashboard page + And I follow "Product listings" + And I follow "Create Product listing" + And I fill in "Code" with "productTest" + And I fill in "Price" with "10" + And I fill in "Original price" with "20" + And I fill in "Minimum price" with "30" + And I fill in "Name" with "test" + And I fill in "Slug" with "product" + When I click "Save" button + Then I should see "This form contains errors." diff --git a/OpenMarketplace/features/vendor/create_product_listing_and_verify.feature b/OpenMarketplace/features/vendor/create_product_listing_and_verify.feature new file mode 100644 index 0000000..6caad71 --- /dev/null +++ b/OpenMarketplace/features/vendor/create_product_listing_and_verify.feature @@ -0,0 +1,22 @@ +@vendor_managing_product_listings +Feature: Creating a product listing + and sending it for verification. + As a vendor, I must be able to create + a product with a submission for verification. + + Background: + Given there is an "verified" vendor user "vendor" with password "vendor" + And I am logged in as "vendor@email.com" + And the store operates on a channel named "Web-US" in "USD" currency + + @ui + Scenario: Creating product listing and sending to verification + When I am on a dashboard page + And I follow "Product list" + And I follow "Create Product" + And I fill form with default data + And I click "Save draft" button + And I follow "Product list" + And I click "Send for verification" button + Then I should see product's listing status "Under verification" + And I should see "Product listing sent to verification." diff --git a/OpenMarketplace/features/vendor/create_product_listing_with_attributes.feature b/OpenMarketplace/features/vendor/create_product_listing_with_attributes.feature new file mode 100644 index 0000000..51758b2 --- /dev/null +++ b/OpenMarketplace/features/vendor/create_product_listing_with_attributes.feature @@ -0,0 +1,25 @@ +@vendor_managing_product_listings +Feature: Creating a product listing with attribute + and sending it for verification. + As a vendor, I must be able to create + a product with a submission for verification. + + Background: + Given there is an "verified" vendor user "vendor" with password "vendor" + And the store operates on a channel named "Web-US" in "USD" currency + And I am logged in as "vendor@email.com" + And there is draft attribute with code "extended" and type "checkbox" + And there is draft attribute with code "universal" and type "checkbox" + + @ui + Scenario: Creating product listing and sending to verification + When I am on a dashboard page + And I follow "Product list" + And I follow "Create Product" + And I fill form with default data + And I select "extended" from "sylius_product_attribute_choice" + And I click "Save" button + And I follow "Product list" + And I click "Send for verification" button + And I click "confirmation-button" on confirmation modal + Then I should see "Under verification" diff --git a/OpenMarketplace/features/vendor/create_product_listing_with_tax_category.feature b/OpenMarketplace/features/vendor/create_product_listing_with_tax_category.feature new file mode 100644 index 0000000..cf9444b --- /dev/null +++ b/OpenMarketplace/features/vendor/create_product_listing_with_tax_category.feature @@ -0,0 +1,62 @@ +@vendor_managing_product_listings +Feature: Creating a product listing + with Tax Category filled. + As a vendor, I must be able to create + a product with a Tax Category for verification. + + Background: + Given there is an admin user "admin" with password "admin" + And there is an "verified" vendor user "vendor" with password "vendor" + And I am logged in as "vendor@email.com" + And the store operates on a channel named "en_US" in "USD" currency + And there is tax category "Clothing" with code "clothing" + And there is tax category "Other" with code "other" + + @ui + Scenario: Creating product listing with a tax category and sending to verification + When I am on a dashboard page + And I follow "Product listings" + And I follow "Create Product listing" + And I fill form with default data + And I fill in Tax category with "clothing" + And I click "Save draft" button + And I follow "Product listings" + And I click "Send for verification" button + And I should see product's listing status "Under verification" + Then I should see "Product listing sent to verification." + + @ui + Scenario: Admin accepts product listing with a tax category + Given There is an under verification product listing created by vendor + And This product draft has Tax category named "Other" + And I am logged in as an admin + And I am on an admin dashboard page + And I follow "Product listings" + And I should see 1 product listing + And I follow "Details" + And I should see taxCategory "Other" for product listing + And I click "Accept" button + And I follow "Products" + And I follow "Details" + Then I should see taxCategory "Other" for product listing + + @ui + Scenario: Admin rejects product listing with a tax category + Given There is an under verification product listing created by vendor + And This product draft has Tax category named "Other" + And I am logged in as an admin + And I am on an admin dashboard page + And I follow "Product listings" + And I should see 1 product listing + And I follow "Details" + And I should see taxCategory "Other" for product listing + And I fill in conversation message content with "reason to reject" + Then I click "Reject" button + + @ui + Scenario: Vendor gets the product listing reject message + Given There is a rejected product listing created by vendor + And I am logged in as "vendor@email.com" + When I am on a dashboard page + And I am on a conversations page + Then I should see "Listing with selected tax category was rejected" diff --git a/OpenMarketplace/features/vendor/create_product_listing_with_taxons.feature b/OpenMarketplace/features/vendor/create_product_listing_with_taxons.feature new file mode 100644 index 0000000..82c0821 --- /dev/null +++ b/OpenMarketplace/features/vendor/create_product_listing_with_taxons.feature @@ -0,0 +1,21 @@ +@vendor_managing_product_listings +Feature:Creating a product listing. + As a vendor, I need to be able + to create a product attached to taxons. + + Background: + Given there is an "verified" vendor user "vendor" with password "vendor" + And I am logged in as "vendor@email.com" + And the store classifies its products as "Caps" and "Shoes" + And the store operates on a channel named "Web-US" in "USD" currency + + @ui + Scenario: Creating product listing + When I am on a dashboard page + And I follow "Product list" + And I follow "Create Product" + And I fill form with default data + And I choose main taxon "Caps" + And I click "Save" button + Then I should see product's listing status "Created" + And I should see "Product listing created." diff --git a/OpenMarketplace/features/vendor/create_product_listing_without_price.feature b/OpenMarketplace/features/vendor/create_product_listing_without_price.feature new file mode 100644 index 0000000..ab88d91 --- /dev/null +++ b/OpenMarketplace/features/vendor/create_product_listing_without_price.feature @@ -0,0 +1,23 @@ +@vendor_managing_product_listings +Feature:Creating a product listing without price. + As a vendor, I shouldn't be able + to create a product. + + Background: + Given there is an "verified" vendor user "vendor" with password "vendor" + And I am logged in as "vendor@email.com" + And the store operates on a channel named "Web-US" in "USD" currency + + @ui + Scenario: + Given I am on "/" + And I follow "My account" + And I follow "Product listings" + And I follow "Create Product listing" + And I fill in "Code" with "productTest" + And I fill in "Original price" with "20" + And I fill in "Minimum price" with "30" + And I fill in "Name" with "test" + And I fill in "Slug" with "product" + When I click "Save draft" button + Then I should get validation error diff --git a/OpenMarketplace/features/vendor/customer_can_see_vendors_sidebar.feature b/OpenMarketplace/features/vendor/customer_can_see_vendors_sidebar.feature new file mode 100644 index 0000000..3604471 --- /dev/null +++ b/OpenMarketplace/features/vendor/customer_can_see_vendors_sidebar.feature @@ -0,0 +1,23 @@ +@customer_dashboard +Feature: Customer can view vendors specific options + + Background: + Given the store operates on a single channel in "United States" + And the store operates in "Poland" + + @ui + Scenario: Showing verified vendor specific options + Given there is a "verified" vendor user "test@company.domain" registered in country "PL" + And I am logged in as "test@company.domain" + When I am on "/en_US/account/dashboard" + Then I should see "Profile" inside sidebar + And I should not see "Become a Vendor" inside sidebar + + @ui + Scenario: Showing unverified vendor specific options + Given there is a "unverified" vendor user "test@company.domain" registered in country "PL" + And I am logged in as "test@company.domain" + When I am on "/en_US/account/dashboard" + Then I should see "Become a Vendor" inside sidebar + And I should not see "Profile" inside sidebar + diff --git a/OpenMarketplace/features/vendor/deleting_product_listing.feature b/OpenMarketplace/features/vendor/deleting_product_listing.feature new file mode 100644 index 0000000..a3a36bd --- /dev/null +++ b/OpenMarketplace/features/vendor/deleting_product_listing.feature @@ -0,0 +1,17 @@ +@product_removal_vendor +Feature: Hiding product listing visibility + As a vendor i can hide product listing + + Background: + Given there is an "verified" vendor user "vendor" with password "vendor" + And I am logged in as "vendor@email.com" + And the store operates on a channel named "Web-US" in "USD" currency + + @ui + Scenario: Deleting product listing + Given there is 1 product listing created by vendor + And Product listing status is "Created" + And I am on "/en_US/account/vendor/product-listings" + Then I should see "Remove" + And I click "Remove" button + Then I should see "There are no results to display" diff --git a/OpenMarketplace/features/vendor/draft_attribute.feature b/OpenMarketplace/features/vendor/draft_attribute.feature new file mode 100644 index 0000000..a843b2d --- /dev/null +++ b/OpenMarketplace/features/vendor/draft_attribute.feature @@ -0,0 +1,14 @@ +@draft_attribute +Feature: Vendor can create attributes for product listings + + Background: + Given the store operates on a single channel in "United States" + And the store operates in "Poland" + And there is a "verified" vendor user "test@company.domain" registered in country "PL" + And I am logged in as "test@company.domain" + + @ui + Scenario: Creating text type attribute + Given I am on "/en_US/account/vendor/product-attributes/text/new" + And I fill form with "code" and name with "name" and submit + Then I should see attribute with "code" and "name" type "Text" diff --git a/OpenMarketplace/features/vendor/editing_existing_product_listing.feature b/OpenMarketplace/features/vendor/editing_existing_product_listing.feature new file mode 100644 index 0000000..077b4b7 --- /dev/null +++ b/OpenMarketplace/features/vendor/editing_existing_product_listing.feature @@ -0,0 +1,33 @@ +@vendor_managing_product_listings +Feature: Editing a product listing. + As a vendor, after I have saved new draft of already existing + product listing, admin must see "Created" status set for this + product listing. + + Background: + Given there is an "verified" vendor user "vendor" with password "vendor" + And I am logged in as "vendor@email.com" + And the store operates on a channel named "Web-US" in "USD" currency + And there is an admin user "admin" with password "password" + And the channel uses another locale "pl" + + @ui + Scenario: Accept product listing + Given there is 1 product listing created by vendor with status "verified" + When I am on "/" + And I follow "My account" + And I follow "Product listings" + And I follow "Edit" + And I fill form with default data + And I click "Save draft" button + And I follow "Product listings" + Then I should see product's listing status "Created" + + @ui + Scenario: Admin see product listing with status created + Given there is 1 product listing created by vendor with status "Created" + And I am logged in as an admin + When I am on "/admin" + And I follow "Product listings" + Then I should see product's listing status "Created" + diff --git a/OpenMarketplace/features/vendor/editing_removed_product_listing.feature b/OpenMarketplace/features/vendor/editing_removed_product_listing.feature new file mode 100644 index 0000000..308cccf --- /dev/null +++ b/OpenMarketplace/features/vendor/editing_removed_product_listing.feature @@ -0,0 +1,18 @@ +@vendor_managing_product_listings +Feature: Trying to editing removed a product listing. + As a vendor, after I have removed product listing + vendor can't access edit page of this product listing + + Background: + Given there is an "verified" vendor user "vendor" with password "vendor" + And I am logged in as "vendor@email.com" + And the store operates on a channel named "Web-US" in "USD" currency + And there is an admin user "admin" with password "password" + + @ui + Scenario: Trying to edit removed product listing + Given there is 1 product listing created by vendor + And the product listing is removed + When I am on edit page product listing "/en_US/account/vendor/product-listings/edit" + Then I should see "The product listing you are trying to reach has been deleted." + diff --git a/OpenMarketplace/features/vendor/filling_vendor_registration_form_by_a_customer.feature b/OpenMarketplace/features/vendor/filling_vendor_registration_form_by_a_customer.feature new file mode 100644 index 0000000..e69bf73 --- /dev/null +++ b/OpenMarketplace/features/vendor/filling_vendor_registration_form_by_a_customer.feature @@ -0,0 +1,55 @@ +@vendor_register +Feature: Filling vendor registration form by a customer + In order to create new vendor account + As a customer + I can fill registration form + + Background: + Given the store operates on a single channel in "United States" + And I am a logged in customer + + Scenario: Attempting to submit empty form + When I am on "/en_US/account/vendor/register" + And I press "Become a Vendor" + Then I should see "sylius-validation-error" "7" times + + Scenario: Filling form with data that fails validation + When I am on "/en_US/account/vendor/register" + And I fill in "profile_companyName" with "te" + And I fill in "profile_taxIdentifier" with "56" + And I fill in "profile_phoneNumber" with "55" + And I attach the file "images/invalid_logo.png" to "profile_image_file" + And I fill in "profile_description" with "ab" + And I fill in "profile_vendorAddress_city" with "an" + And I fill in "profile_vendorAddress_street" with "et" + And I fill in "profile_vendorAddress_postalCode" with "de" + And I press "Become a Vendor" + Then I should see "sylius-validation-error" "8" times + + Scenario: Correct completion of the form + When I am on "/en_US/account/vendor/register" + And I fill in "profile_companyName" with "testCompanyName" + And I fill in "profile_taxIdentifier" with "6546546456" + And I fill in "profile_phoneNumber" with "555555555" + And I fill in "profile_description" with "description" + And I fill in "profile_vendorAddress_city" with "Milan" + And I fill in "profile_vendorAddress_street" with "test_street" + And I fill in "profile_vendorAddress_postalCode" with "test_postalCode" + And I press "Become a Vendor" + Then I should see "Thank you for filling the Vendor registration form. Your request now will be reviewed by our administrators" + And I should see "Your vendor account is under verification." + + Scenario: Correct completion of the form with logo + When I am on "/en_US/account/vendor/register" + And I fill in "profile_companyName" with "testCompanyName" + And I fill in "profile_taxIdentifier" with "6546546456" + And I fill in "profile_phoneNumber" with "555555555" + And I attach the file "images/valid_logo.png" to "profile_image_file" + And I fill in "profile_description" with "description" + And I fill in "profile_vendorAddress_city" with "Milan" + And I fill in "profile_vendorAddress_street" with "test_street" + And I fill in "profile_vendorAddress_postalCode" with "test_postalCode" + And I press "Become a Vendor" + Then I should see "Thank you for filling the Vendor registration form. Your request now will be reviewed by our administrators" + And I should see "Your vendor account is under verification." + diff --git a/OpenMarketplace/features/vendor/inventory_management.feature b/OpenMarketplace/features/vendor/inventory_management.feature new file mode 100644 index 0000000..18a3209 --- /dev/null +++ b/OpenMarketplace/features/vendor/inventory_management.feature @@ -0,0 +1,63 @@ +@inventory_management +Feature: Vendor can manage his inventory + As a Vendor I can set products as tracked and untracked + Also i can change products on hand count + + Background: + Given the store operates on a single channel in "United States" + And the store operates in "Poland" + And there is a "verified" vendor user "test@company.domain" registered in country "PL" + And I am logged in as "test@company.domain" + + @ui + Scenario: Setting a product as tracked + Given There is a product with variant code "testing_variant_code" owned by logged in vendor + And I am on "/en_US/account/vendor/product-variants/inventory" + And I follow "Edit" + And I fill in "sylius_product_variant[onHand]" with "12" + And I set product as tracked + And I submit inventory form + Then I should see "12 Available on hand" + + @ui + Scenario: Setting a product as tracked + Given There is a product with variant code "testing_variant_code" owned by logged in vendor + And I am on "/en_US/account/vendor/product-variants/inventory" + And I follow "Edit" + And I fill in "sylius_product_variant[onHand]" with "12" + And I set product as untracked + And I submit inventory form + Then I should see "Not tracked" + + @ui + Scenario: Setting a product as tracked and order this product + Given There is a product with variant code "testing_variant_code" owned by logged in vendor + And I am on "/en_US/account/vendor/product-variants/inventory" + And I follow "Edit" + And I fill in "sylius_product_variant[onHand]" with "5" + And I set product as tracked + And I submit inventory form + And I have product "testing_variant_code" in cart + And I am on "/en_US/checkout/address" + And I fill in "sylius_checkout_address[billingAddress][firstName]" with "Test name" + And I fill in "sylius_checkout_address[billingAddress][lastName]" with "Test name" + And I fill in "sylius_checkout_address[billingAddress][company]" with "Test company" + And I fill in "sylius_checkout_address[billingAddress][street]" with "Test street" + And I select "United States" from "sylius_checkout_address[billingAddress][countryCode]" + And I fill in "sylius_checkout_address[billingAddress][city]" with "Test city" + And I fill in "sylius_checkout_address[billingAddress][postcode]" with "Test code" + And I submit form + And I choose shipment + And I choose payment + And I complete checkout + Then product on hand count should be "4" + + @ui + Scenario: Setting to big on hand amount + Given There is a product with variant code "testing_variant_code" owned by logged in vendor + When I am on "/en_US/account/vendor/product-variants/inventory" + And I follow "Edit" + And I fill in "sylius_product_variant[onHand]" with "1000000001" + And I submit inventory form + Then I should see "This value should be less than or equal to 1000000000." + diff --git a/OpenMarketplace/features/vendor/order_details.feature b/OpenMarketplace/features/vendor/order_details.feature new file mode 100644 index 0000000..b89d8d7 --- /dev/null +++ b/OpenMarketplace/features/vendor/order_details.feature @@ -0,0 +1,43 @@ +@order_details +Feature: Vendor can view order details + In order to view order details + As a vendor I want to visit page + + Background: + Given the store operates on a single channel in "United States" + And the store operates in "Poland" + And the store allows shipping with "fedex" + And there is a "verified" vendor user "test@company.domain" registered in country "PL" + And I am logged in as "test@company.domain" + And I am on "en_US/account" + + @ui + Scenario: Visiting details page + Given There is order with property "number" with value "55" made with logged in seller + And The order is made by customer with first name "Adam" + And this order has new shipping address city: "Warsaw", postalCode: "12-345", street: "ul. New" + And this order has new billing address city: "Warsaw", postalCode: "45-566", street: "ul. Old" + And this order has new shipment + When I visit order details page + Then I should see order with number "55" + And I should see customer details with name "Adam" + And I should see customer shipping address "ul. New Warsaw" + And I should see customer shipping address "12-345" + And I should see customer billing address "ul. Old Warsaw" + And I should see customer billing address "45-566" + And I should see shipping state "Ready" + + @ui + Scenario: Visiting details page with shipped order + Given There is order with property "number" with value "53" made with logged in seller + And this order has new shipment + And this order has already been shipped + When I visit order details page + Then I should see order with number "53" + And I should see shipping state "Shipped" + + @ui + Scenario: Visiting details page + Given There is order with property "number" with value "55" made with other seller + When I try to open order details page + Then the response status code should be 404 diff --git a/OpenMarketplace/features/vendor/order_listing.feature b/OpenMarketplace/features/vendor/order_listing.feature new file mode 100644 index 0000000..5d67846 --- /dev/null +++ b/OpenMarketplace/features/vendor/order_listing.feature @@ -0,0 +1,74 @@ +@order_listing +Feature: Vendor can see his orders + In order to view orders + As a Vendor + I want to visit orders listing page + + Background: + Given the store operates on a single channel in "United States" + And the store operates in "Poland" + And there is a "verified" vendor user "test@company.domain" registered in country "PL" + And I am logged in as "test@company.domain" + + @ui + Scenario: Rendering all orders + Given There is order with property "state" with value "new" made with logged in seller + And There is order with property "state" with value "completed" made with logged in seller + And I am on "/en_US/account/vendor/orders" + Then I should see "2" orders + + + @ui + Scenario: Filtering by state + Given There is order with property "state" with value "new" made with logged in seller + And There is order with property "state" with value "completed" made with logged in seller + And I am on "/en_US/account/vendor/orders" + And I select "New" from "criteria[state]" + And I click "Filter" + Then I should see "1" orders + + @ui + Scenario: Filtering by payment state + Given There is order with property "paymentState" with value "awaiting_payment" made with logged in seller + And There is order with property "paymentState" with value "paid" made with logged in seller + And There is order with property "paymentState" with value "cancelled" made with logged in seller + And I am on "/en_US/account/vendor/orders" + And I select "Cancelled" from "criteria[paymentState]" + And I click "Filter" + Then I should see "1" orders + And I select "All" from "criteria[paymentState]" + And I click "Filter" + Then I should see "3" orders + + @ui + Scenario: Filtering by shipping state + Given There is order with property "shippingState" with value "ready" made with logged in seller + And There is order with property "shippingState" with value "shipped" made with logged in seller + And There is order with property "shippingState" with value "cancelled" made with logged in seller + And I am on "/en_US/account/vendor/orders" + And I select "Ready" from "criteria[shippingState]" + And I click "Filter" + Then I should see "1" orders + And I select "All" from "criteria[shippingState]" + And I click "Filter" + Then I should see "3" orders + + @ui + Scenario: Filtering by update date + Given There is order with property "checkoutCompletedAt" with value "2022-01-01" made with logged in seller + And There is order with property "checkoutCompletedAt" with value "2022-01-02" made with logged in seller + And There is order with property "checkoutCompletedAt" with value "2022-01-03" made with logged in seller + And I am on "/en_US/account/vendor/orders" + And I fill in "criteria[date][from][date]" with "2022-01-01" + And I fill in "criteria[date][to][date]" with "2022-01-02" + And I click "Filter" + Then I should see "2" orders + + @ui + Scenario: Orders list pagination + Given There is "5" orders made with logged in seller + And I am on "/en_US/account/vendor/orders" + And Pagination is set to display "2" orders per page + Then I should see "2" orders on page "1" + And I should see "2" orders on page "2" + And I should see "1" orders on page "3" diff --git a/OpenMarketplace/features/vendor/product_revies/filter_reviews.feature b/OpenMarketplace/features/vendor/product_revies/filter_reviews.feature new file mode 100644 index 0000000..2b76f1f --- /dev/null +++ b/OpenMarketplace/features/vendor/product_revies/filter_reviews.feature @@ -0,0 +1,60 @@ +@product_reviews +Feature: Vendor can filter reviews of his products + In order to filter reviews. + As a Vendor I want to filter reviews + + Background: + Given the store operates on a single channel in "United States" + And the store operates in "Poland" + And the store has customer "Alex Holannd" with email "alex@honnold.pl" + And there is a "verified" vendor user "kim@jain.pl" registered in country "PL" + And I am logged in as "kim@jain.pl" + And There is a product with variant code "Quickdraws-x6" owned by logged in vendor + And this product has a new review titled "Good" and rated 4 added by customer "alex@honnold.pl" + And there is a "verified" vendor user "addam@ondra.pl" registered in country "PL" + And I am logged in as "addam@ondra.pl" + + + @ui + Scenario: Filtering new reviews of a product + Given There is a product with variant code "Quickdraws-x5" owned by logged in vendor + And this product has a new review titled "Good" and rated 4 added by customer "alex@honnold.pl" + And this product has one review from customer "kim@jain.pl" + And I am on "/en_US/account/vendor/product-reviews" + When I select "New" from "criteria[status]" + And I click "Filter" + Then I should see "1" reviews + + @ui + Scenario: Filtering accepted reviews of a product + Given There is a product with variant code "Quickdraws-x5" owned by logged in vendor + And this product has a new review titled "The best" and rated 5 added by customer "addam@ondra.pl" + And this product has one review from customer "alex@honnold.pl" + And this product has one review from customer "kim@jain.pl" + And I am on "/en_US/account/vendor/product-reviews" + When I select "Accepted" from "criteria[status]" + And I click "Filter" + Then I should see "2" reviews + + @ui + Scenario: Filtering accepted reviews of a product + Given There is a product with variant code "Quickdraws-x5" owned by logged in vendor + And this product also has review rated 2 which is rejected + And this product also has review rated 1 which is rejected + And this product also has review rated 1 which is rejected + And I am on "/en_US/account/vendor/product-reviews" + When I select "Rejected" from "criteria[status]" + And I click "Filter" + Then I should see "3" reviews + + @ui + Scenario: Filtering by rating + Given There is a product with variant code "Helmet" owned by logged in vendor + And this product has one review from customer "alex@honnold.pl" + And this product has a new review titled "No good" and rated 1 added by customer "kim@jain.pl" + And There is a product with variant code "Helmet XL" owned by logged in vendor + And this product has a new review titled "Bad" and rated 1 added by customer "kim@jain.pl" + And I am on "/en_US/account/vendor/product-reviews" + When I select "1" from "criteria[rating]" + And I click "Filter" + Then I should see "2" reviews diff --git a/OpenMarketplace/features/vendor/product_revies/reviews_accept.feature b/OpenMarketplace/features/vendor/product_revies/reviews_accept.feature new file mode 100644 index 0000000..8bb3fd1 --- /dev/null +++ b/OpenMarketplace/features/vendor/product_revies/reviews_accept.feature @@ -0,0 +1,33 @@ +@product_reviews +Feature: Vendor can accept reviews of his products + In order to manage reviews. + As a Vendor I want to accept reviews + + Background: + Given the store operates on a single channel in "United States" + And the store operates in "Poland" + And the store has customer "Alex Holannd" with email "alex@honnold.pl" + And there is a "verified" vendor user "kim@jain.pl" registered in country "PL" + And I am logged in as "kim@jain.pl" + And There is a product with variant code "Quickdraws-x6" owned by logged in vendor + And this product has a new review titled "Good" and rated 4 added by customer "alex@honnold.pl" + And there is a "verified" vendor user "addam@ondra.pl" registered in country "PL" + And I am logged in as "addam@ondra.pl" + + @ui + Scenario: Accepting a review of a product + Given There is a product with variant code "Quickdraws-x5" owned by logged in vendor + And this product has a new review titled "Good" and rated 4 added by customer "alex@honnold.pl" + And this product has a new review titled "The best" and rated 5 added by customer "kim@jain.pl" + And I am on "/en_US/account/vendor/product-reviews" + When I click "Accept" first review + Then this product has 1 "Accepted" reviews + + @ui + Scenario: Accepting a review of a product when there is one accepted + Given There is a product with variant code "Quickdraws-x5" owned by logged in vendor + And this product has a new review titled "Good" and rated 4 added by customer "alex@honnold.pl" + And this product has one review from customer "kim@jain.pl" + And I am on "/en_US/account/vendor/product-reviews" + When I click "Accept" first review + Then this product has 2 "Accepted" reviews diff --git a/OpenMarketplace/features/vendor/product_revies/reviews_delete.feature b/OpenMarketplace/features/vendor/product_revies/reviews_delete.feature new file mode 100644 index 0000000..71a62a2 --- /dev/null +++ b/OpenMarketplace/features/vendor/product_revies/reviews_delete.feature @@ -0,0 +1,44 @@ +@product_reviews +Feature: Vendor can delete reviews of his products + In order to manage reviews. + As a Vendor I want to delete reviews + + Background: + Given the store operates on a single channel in "United States" + And the store operates in "Poland" + And the store has customer "Alex Holannd" with email "alex@honnold.pl" + And there is a "verified" vendor user "kim@jain.pl" registered in country "PL" + And I am logged in as "kim@jain.pl" + And There is a product with variant code "Quickdraws-x6" owned by logged in vendor + And this product has a new review titled "Good" and rated 4 added by customer "alex@honnold.pl" + And there is a "verified" vendor user "addam@ondra.pl" registered in country "PL" + And I am logged in as "addam@ondra.pl" + + + @ui + Scenario: Deleting a new review of a product + Given There is a product with variant code "Quickdraws-x5" owned by logged in vendor + And this product has a new review titled "Good" and rated 4 added by customer "alex@honnold.pl" + And this product has a new review titled "Good" and rated 4 added by customer "kim@jain.pl" + And I am on "/en_US/account/vendor/product-reviews" + When I click "Delete" first review + Then this product has 1 "New" reviews + + @ui + Scenario: Deleting a accepted review of a product + Given There is a product with variant code "Quickdraws-x5" owned by logged in vendor + And this product has one review from customer "kim@jain.pl" + And this product has a new review titled "The best" and rated 5 added by customer "alex@honnold.pl" + And I am on "/en_US/account/vendor/product-reviews" + When I click "Delete" first review + Then this product has 0 "Accepted" reviews + + @ui + Scenario: Deleting a rejected review of a product + Given There is a product with variant code "Quickdraws-x5" owned by logged in vendor + And this product also has review rated 2 which is rejected + And this product also has review rated 1 which is rejected + And this product also has review rated 1 which is rejected + And I am on "/en_US/account/vendor/product-reviews" + When I click "Delete" first review + Then this product has 2 "Rejected" reviews diff --git a/OpenMarketplace/features/vendor/product_revies/reviews_edit.feature b/OpenMarketplace/features/vendor/product_revies/reviews_edit.feature new file mode 100644 index 0000000..7360547 --- /dev/null +++ b/OpenMarketplace/features/vendor/product_revies/reviews_edit.feature @@ -0,0 +1,52 @@ +@product_reviews +Feature: Vendor can edit reviews of his products + In order to manage reviews. + As a Vendor I want to edit reviews + + Background: + Given the store operates on a single channel in "United States" + And the store operates in "Poland" + And the store has customer "Alex Holannd" with email "alex@honnold.pl" + And there is a "verified" vendor user "kim@jain.pl" registered in country "PL" + And I am logged in as "kim@jain.pl" + And There is a product with variant code "Quickdraws-x6" owned by logged in vendor + And this product has a new review titled "Good" and rated 4 added by customer "alex@honnold.pl" + And there is a "verified" vendor user "addam@ondra.pl" registered in country "PL" + And I am logged in as "addam@ondra.pl" + + @ui + Scenario: Editing title of new review of a product + Given There is a product with variant code "Quickdraws-x5" owned by logged in vendor + And this product has a new review titled "Good" and rated 4 added by customer "alex@honnold.pl" + And this product has a new review titled "Good" and rated 4 added by customer "kim@jain.pl" + And I am on edit page of review added by "kim@jain.pl" to this product + When I fill in "product_review[title]" with "New title" + And I click "Save changes" + Then I should be on "/en_US/account/vendor/product-reviews" + And this review should have name "New title" + + @ui + Scenario: Editing comment of accepted review of a product + Given There is a product with variant code "Quickdraws-x5" owned by logged in vendor + And this product has a new review titled "The best" and rated 5 added by customer "addam@ondra.pl" + And this product has one review from customer "alex@honnold.pl" + And this product has one review from customer "kim@jain.pl" + And I am on edit page of review added by "kim@jain.pl" to this product + When I fill in "product_review[comment]" with "New comment" + And I click "Save changes" + Then I should be on "/en_US/account/vendor/product-reviews" + And this review should have comment "New comment" + + @ui + Scenario: Editing title and comment of rejected review of a product + Given There is a product with variant code "Quickdraws-x5" owned by logged in vendor + And this product also has review rated 2 which is rejected + And this product also has review rated 1 which is rejected + And this product also has review rated 1 which is rejected + And I am on edit page of review added by "alex@honnold.pl" to this product + When I fill in "product_review[title]" with "New title" + And I fill in "product_review[comment]" with "New comment" + And I click "Save changes" + Then I should be on "/en_US/account/vendor/product-reviews" + And this review should have name "New title" + And this review should have comment "New comment" diff --git a/OpenMarketplace/features/vendor/product_revies/reviews_listing.feature b/OpenMarketplace/features/vendor/product_revies/reviews_listing.feature new file mode 100644 index 0000000..da5fd4b --- /dev/null +++ b/OpenMarketplace/features/vendor/product_revies/reviews_listing.feature @@ -0,0 +1,30 @@ +@product_reviews +Feature: Vendor can view reviews of his products + In order to manage reviews. + As a Vendor I want to visit page + + Background: + Given the store operates on a single channel in "United States" + And the store operates in "Poland" + And the store has customer "Alex Holand" with email "alex@honnold.pl" + And there is a "verified" vendor user "kim@jain.pl" registered in country "PL" + And I am logged in as "kim@jain.pl" + And There is a product with variant code "Quickdraws-x6" owned by logged in vendor + And this product has a new review titled "Good" and rated 4 added by customer "alex@honnold.pl" + And there is a "verified" vendor user "addam@ondra.pl" registered in country "PL" + And I am logged in as "addam@ondra.pl" + And There is a product with variant code "Quickdraws-x5" owned by logged in vendor + And this product has a new review titled "Good" and rated 4 added by customer "alex@honnold.pl" + + + @ui + Scenario: Rendering all reviews of Vendor's product + When I go to "/en_US/account/vendor/product-reviews" + Then I should see "1" reviews + + @ui + Scenario: Rendering all reviews of Vendor's product when there are three different + Given this product has one review from customer "kim@jain.pl" + And this product also has review rated 1 which is rejected + When I go to "/en_US/account/vendor/product-reviews" + Then I should see "3" reviews diff --git a/OpenMarketplace/features/vendor/product_revies/reviews_reject.feature b/OpenMarketplace/features/vendor/product_revies/reviews_reject.feature new file mode 100644 index 0000000..0ee1fa7 --- /dev/null +++ b/OpenMarketplace/features/vendor/product_revies/reviews_reject.feature @@ -0,0 +1,25 @@ +@product_reviews +Feature: Vendor can reject reviews of his products + In order to manage reviews. + As a Vendor I want to reject reviews + + Background: + Given the store operates on a single channel in "United States" + And the store operates in "Poland" + And the store has customer "Alex Holannd" with email "alex@honnold.pl" + And there is a "verified" vendor user "kim@jain.pl" registered in country "PL" + And I am logged in as "kim@jain.pl" + And There is a product with variant code "Quickdraws-x6" owned by logged in vendor + And this product has a new review titled "Good" and rated 4 added by customer "alex@honnold.pl" + And there is a "verified" vendor user "addam@ondra.pl" registered in country "PL" + And I am logged in as "addam@ondra.pl" + + + @ui + Scenario: Rejecting review of a product + Given There is a product with variant code "Quickdraws-x5" owned by logged in vendor + And this product has a new review titled "Good" and rated 4 added by customer "alex@honnold.pl" + And this product has one review from customer "kim@jain.pl" + And I am on "/en_US/account/vendor/product-reviews" + When I click "Reject" first review + Then this product has 1 "Rejected" reviews diff --git a/OpenMarketplace/features/vendor/resend_order_confirmation.feature b/OpenMarketplace/features/vendor/resend_order_confirmation.feature new file mode 100644 index 0000000..a75273a --- /dev/null +++ b/OpenMarketplace/features/vendor/resend_order_confirmation.feature @@ -0,0 +1,20 @@ +@order_details +Feature: Resending an order confirmation email for a chosen order + In order to be able to send a lost email again + As an Vendor + I want to have the order confirmation email for a chosen order sent to the customer + + Background: + Given the store operates on a single channel in "United States" + And the store operates in "Poland" + And the store allows shipping with "fedex" + And there is a "verified" vendor user "test@company.domain" registered in country "PL" + And I am logged in as "test@company.domain" + + @ui + Scenario: Resending a confirmation email for a given order + Given There is order with property "number" with value "55" made with logged in seller + And this order has new shipment + When I visit order details page + And I resend the order confirmation email as vendor + Then I should see "Order confirmation has been successfully resent to the customer." \ No newline at end of file diff --git a/OpenMarketplace/features/vendor/seeing_customer_details.feature b/OpenMarketplace/features/vendor/seeing_customer_details.feature new file mode 100644 index 0000000..df6007a --- /dev/null +++ b/OpenMarketplace/features/vendor/seeing_customer_details.feature @@ -0,0 +1,25 @@ +@customers_details +Feature: Seeing customer's details as vendor + In order to see customer's details in the store + As a Vendor + I want to be able to show specific customer's page + + Background: + Given the store operates on a single channel in "United States" + And the store operates in "Poland" + And there is a "verified" vendor user "test@company.domain" registered in country "PL" + And I am logged in as "test@company.domain" + + @ui + Scenario: Seeing customers details page that placed an order with current Vendor + Given There is order with property "state" with value "new" made with logged in seller + And The order is made by customer with first name "TestingClient" + And I am on customer details page + Then I should see customer details with name "TestingClient" + + @ui + Scenario: Not seeing customers details page that placed an order with different Vendor + Given There is order with property "state" with value "new" made with other seller + And The order is made by customer with first name "TestingClient" + And I am on customer details page + Then I should not see customer with name "TestingClient" diff --git a/OpenMarketplace/features/vendor/seeing_vendors_cutomer_orders.feature b/OpenMarketplace/features/vendor/seeing_vendors_cutomer_orders.feature new file mode 100644 index 0000000..5d0a05d --- /dev/null +++ b/OpenMarketplace/features/vendor/seeing_vendors_cutomer_orders.feature @@ -0,0 +1,26 @@ +@order_listing +Feature: Vendor can see his customer's orders + In order to view customer's orders + As a Vendor + I want to visit customer's listing page + + Background: + Given the store operates on a single channel in "United States" + And the store operates in "Poland" + And there is a "verified" vendor user "test@company.domain" registered in country "PL" + And I am logged in as "test@company.domain" + + @ui + Scenario: Seeing customers orders from customers + Given There is order with property "state" with value "new" made with logged in seller + And I am on "/en_US/account/vendor/customers" + And I follow "Show orders" + Then I should see "1" orders + + @ui + Scenario: Seeing customers orders from customer details + Given There is order with property "state" with value "new" made with logged in seller + And I am on "/en_US/account/vendor/customers" + And I follow "Show" + And I follow "Show orders" + Then I should see "1" orders diff --git a/OpenMarketplace/features/vendor/settlements.feature b/OpenMarketplace/features/vendor/settlements.feature new file mode 100644 index 0000000..ac3ed0c --- /dev/null +++ b/OpenMarketplace/features/vendor/settlements.feature @@ -0,0 +1,44 @@ +@vendor_settlements +Feature: Vendor can manage settlements + In order to settle my settlements + As a Vendor + I want to visit settlements page, filter and accept them + + Background: + Given the store operates on a channel named "United States" + And there is a "verified" vendor user "test@company.domain" registered in country with code "US" + And I am logged in as "test@company.domain" + + @ui + Scenario: Vendor can see settlements + Given there is a "new" settlement with total amount of "100.00" and commission amount of "10.00" + And there is a "accepted" settlement with total amount of "540.00" and commission amount of "74.00" + And there is a "settled" settlement with total amount of "130.00" and commission amount of "12.71" + When I visit the vendor settlements page + Then I should see 3 settlements + + @ui + Scenario: Vendor can not accept settlements with status other than "New" + Given there is a "accepted" settlement + And there is a "settled" settlement + When I visit the vendor settlements page + Then I should not see any accept button + + @ui + Scenario: Vendor can accept new settlements + Given there is a "new" settlement + When I visit the vendor settlements page + And I accept first possible settlement + Then I should see "Settlement has been accepted successfully." + And I should see 1 settlements with status "Settled" + And I should see 0 settlements with status "New" + + @ui + Scenario: Vendor can filter settlements by status + Given there is a "new" settlement with total amount of "100.00" and commission amount of "10.00" + And there is a "accepted" settlement with total amount of "540.00" and commission amount of "74.00" + And there is a "accepted" settlement with total amount of "130.00" and commission amount of "12.71" + When I visit the vendor settlements page + And I filter settlements by status "Accepted" + Then I should see 2 settlements + And I should see 0 settlements with status "New" diff --git a/OpenMarketplace/features/vendor/shipping_methods.feature b/OpenMarketplace/features/vendor/shipping_methods.feature new file mode 100644 index 0000000..606b31a --- /dev/null +++ b/OpenMarketplace/features/vendor/shipping_methods.feature @@ -0,0 +1,35 @@ +@shipping_methods +Feature: Vendor can modify shipping methods + In order to modify shipping methods + As a Vendor + I want to visit shipping methods page + + Background: + Given the store operates on a channel named "United States" + And the store also operates on another channel named "Poland" + And the store has a zone "United States" with code "US" + And default tax zone is "US" + And there is a "verified" vendor user "test@company.domain" registered in country "US" + And I am logged in as "test@company.domain" + + @ui + Scenario: Attempting to see methods on page + Given I change my current channel to "United States" + And the store has "UPS" shipping method with "$20.00" fee per unit for "United States" channel + And the store has "FEDEX" shipping method with "$20.00" fee per unit for "Poland" channel + And I am on "/en_US/account/vendor/shipping-methods" + Then I should see "UPS" shipping method in "United States" channel + And I should see "FEDEX" shipping method in "Poland" channel + + @ui + Scenario: Attempting to enable method + Given I change my current channel to "United States" + And the store has "UPS" shipping method with "$20.00" fee per unit for "United States" channel and "$20.00" for "Poland" channel + And the store has "FEDEX" shipping method with "$20.00" fee per unit for "Poland" channel + And I am on "/en_US/account/vendor/shipping-methods" + And I enable "UPS" shipping method in "United States" channel + And I click "Save changes" button + And I am on "/en_US/account/vendor/shipping-methods" + Then I should see "UPS" enabled shipping method in "United States" channel + Then I should see "UPS" disabled shipping method in "Poland" channel + And I should see "FEDEX" disabled shipping method in "Poland" channel diff --git a/OpenMarketplace/features/vendor/unverified_vendor_page.feature b/OpenMarketplace/features/vendor/unverified_vendor_page.feature new file mode 100644 index 0000000..02e6aa4 --- /dev/null +++ b/OpenMarketplace/features/vendor/unverified_vendor_page.feature @@ -0,0 +1,13 @@ +@unverified_vendor_page +Feature: Unverified vendor page + In order to disable unverified vendor page + As an customer + I should be redirected to homepage + + @ui + Scenario: Redirecting users to homepage when vendor is unverified + Given the store operates on a single channel in "United States" + And there is a user "user@email.com" + And there is a "unverified" vendor + When I open page "/en_US/vendor/test-company" + Then I should be on "/en_US/" diff --git a/OpenMarketplace/features/vendor/vendor_can_update_profile.feature b/OpenMarketplace/features/vendor/vendor_can_update_profile.feature new file mode 100644 index 0000000..20eefd8 --- /dev/null +++ b/OpenMarketplace/features/vendor/vendor_can_update_profile.feature @@ -0,0 +1,97 @@ +@vendor_dashboard +Feature: Vendor can update his company information + In order to update company information + As a Vendor + I want to fill update company information form + I want also confirm update by visiting url with token + + Background: + Given the store operates on a single channel in "United States" + And the store operates in "Poland" + And there is a "verified" vendor user "test@company.domain" registered in country "PL" + And I am logged in as "test@company.domain" + And the channel has a menu taxon + + Scenario: Navigating to form + When I am on "/en_US/account/dashboard" + Then I follow "Profile" + Then I follow "Edit" + Then I should see "Edit your vendor information" + + Scenario: Filling the form + When I am on "/en_US/account/vendor/profile/update" + And I fill in "profile_companyName" with "Test name" + And I fill in "profile_taxIdentifier" with "test identifier" + And I fill in "profile_bankAccountNumber" with "PL75109024025475369832689779" + And I fill in "profile_phoneNumber" with "test number" + And I fill in "profile_description" with "description" + And I fill in "profile_vendorAddress_city" with "City" + And I fill in "profile_vendorAddress_street" with "test street" + And I fill in "profile_vendorAddress_postalCode" with "22-332" + And I press "Save changes" + Then Pending update data should appear in database + + Scenario: Visiting confirmation link + Given There is pending update data with token value "simpletoken" for logged in vendor + When I am on "/en_US/account/vendor/profile-update/simpletoken" + Then I should see "new ID" + And I should see "New Company" + + Scenario: Filling the form with logo + When I am on "/en_US/account/vendor/profile/update" + And I fill in "profile_companyName" with "Test name" + And I fill in "profile_taxIdentifier" with "test identifier" + And I fill in "profile_bankAccountNumber" with "PL75109024025475369832689779" + And I fill in "profile_phoneNumber" with "test number" + And I attach the file "images/valid_logo.png" to "profile_image_file" + And I fill in "profile_description" with "description" + And I fill in "profile_vendorAddress_city" with "City" + And I fill in "profile_vendorAddress_street" with "test street" + And I fill in "profile_vendorAddress_postalCode" with "22-332" + And I press "Save changes" + Then Pending update data should appear in database + + Scenario: Filling the form with logo that fails validation + When I am on "/en_US/account/vendor/profile/update" + And I fill in "profile_companyName" with "Test name" + And I fill in "profile_taxIdentifier" with "test identifier" + And I fill in "profile_bankAccountNumber" with "PL75109024025475369832689779" + And I fill in "profile_phoneNumber" with "test number" + And I attach the file "images/invalid_logo.png" to "profile_image_file" + And I fill in "profile_description" with "description" + And I fill in "profile_vendorAddress_city" with "City" + And I fill in "profile_vendorAddress_street" with "test street" + And I fill in "profile_vendorAddress_postalCode" with "22-332" + And I press "Save changes" + Then I should see "The image width is too small" + And I should see "Minimum width expected is 100px." + + Scenario: Filling the form with logo that fails file size validation + When I am on "/en_US/account/vendor/profile/update" + And I fill in "profile_companyName" with "Test name" + And I fill in "profile_taxIdentifier" with "test identifier" + And I fill in "profile_bankAccountNumber" with "PL75109024025475369832689779" + And I fill in "profile_phoneNumber" with "test number" + And I attach the file "images/too_big_image.jpg" to "profile_image_file" + And I fill in "profile_description" with "description" + And I fill in "profile_vendorAddress_city" with "City" + And I fill in "profile_vendorAddress_street" with "test street" + And I fill in "profile_vendorAddress_postalCode" with "22-332" + And I press "Save changes" + Then I should see "The file is too large" + And I should see "Allowed maximum size is" + + Scenario: Updating vendor logo + Given vendor have logo attached to profile + When I am on "/en_US/account/vendor/profile/update" + And I attach the file "images/valid_logo.png" to "profile_image_file" + And I press "Save changes" + And I visit confirmation page + Then Logo should be updated + + Scenario: Confirmation that form is initialized with right data + Given there is a "verified" vendor user "test2@company.domain" registered in country "PL" + And I am logged in as "test2@company.domain" + And Vendor company name is "Wayne co." tax ID is "testID" phone number is "333 222 000" + And I am on "/en_US/account/vendor/profile/update" + Then I should see form initialized with "Wayne co." "testID" "333 222 000" diff --git a/OpenMarketplace/features/vendor/vendor_commission.feature b/OpenMarketplace/features/vendor/vendor_commission.feature new file mode 100644 index 0000000..d271f2d --- /dev/null +++ b/OpenMarketplace/features/vendor/vendor_commission.feature @@ -0,0 +1,68 @@ +@vendor_commission +Feature: In case of creating the order + I want the commission to be automatically calculated + + Background: + Given the store operates on a single channel in "United States" + And there is a customer "customer test" with an email "email@example.com" + And I am a logged in customer with name "customer test" + + @ui + Scenario: Picking products from different Vendors with default commission settings + Given store has 5 products from different Vendors with default commission settings + And I have 3 products in cart + And I finalize order + Then commission should be calculated for each secondary order + And commissions should not be calculated for primary orders + + @ui + Scenario: Viewing commission in admin order summary + Given store has 5 products from same Vendor + And I have 3 products in cart + And I finalize order + And I am logged in as an administrator + And I am on "/admin" + And I follow "Orders" + And I follow "Show" + Then I should see valid commission information's + + @ui + Scenario: Viewing commission in admin order summary for order without vendor + Given store has 5 products created by admin + And I have 3 products in cart + And I finalize order + And I am logged in as an administrator + And I am on "/admin" + And I follow "Orders" + And I follow "Show" + Then I should see no commission + + @ui + Scenario: Viewing commission in vendor order summary + Given there is a vendor user "test@company.domain" registered in country "PL" + And store has 5 products from vendor "test@company.domain" + And I have 3 products in cart + And I finalize order + And I am logged in as "test@company.domain" + And I am on "en_US/account" + And I follow "My account" + And I follow "Orders" + And I follow "Show" + Then I should see valid commission information's + + @ui + Scenario: Trying to set negative commission + Given there is a vendor user "test@company.domain" registered in country "PL" + And I am logged in as an administrator + And I am on admin vendor listing page + And I follow "Edit" + And I fill in "Commission" with "-10" + And I click "Save changes" button + Then I should get commission value validation error + + @ui + Scenario: Picking products from different Vendors with random commission settings + Given store has 2 products from different Vendors with random commission settings + And I have 2 products in cart + And I finalize order + Then every secondary order should have valid commission total diff --git a/OpenMarketplace/features/vendor/vendor_page_pagination.feature b/OpenMarketplace/features/vendor/vendor_page_pagination.feature new file mode 100644 index 0000000..96a28cd --- /dev/null +++ b/OpenMarketplace/features/vendor/vendor_page_pagination.feature @@ -0,0 +1,30 @@ +@vendor_page_pagination +Feature: Paginating vendor products + In order to see all vendor products + As an customer + I can see all paginated products + + Background: + Given the store operates on a single channel in "United States" + And there is a user "user@email.com" + And there is a "verified" vendor + And the vendor has 30 products + + @ui + Scenario: Attempting to see page number 2 + Given I am on "/en_US/vendor/test-company" + When I follow "Next" + Then I should be on "/en_US/vendor/test-company?page=2" + And I should see a product with name "product-18" + And the first product should have name "product-10" + And the last product should have name "product-18" + + @ui + Scenario: Attempting to change page items limit to 18 + Given I am on "/en_US/vendor/test-company" + When I follow "18" + Then I should be on "/en_US/vendor/test-company?limit=18" + And I should see a product with name "product-1" + And I should see a product with name "product-18" + And the first product should have name "product-1" + And the last product should have name "product-18" diff --git a/OpenMarketplace/features/vendor/vendor_page_sorting.feature b/OpenMarketplace/features/vendor/vendor_page_sorting.feature new file mode 100644 index 0000000..7585864 --- /dev/null +++ b/OpenMarketplace/features/vendor/vendor_page_sorting.feature @@ -0,0 +1,60 @@ +@vendor_page_sorting +Feature: Sorting vendor products + In order to see vendor products + As an customer + I can sort vendor's products + + Background: + Given the store operates on a single channel in "United States" + And there is a user "user@email.com" + And there is a "verified" vendor + And the vendor has 30 products with different dates and prices + + @ui + Scenario: Sorting products by their position with ascending order + Given I am on "/en_US/vendor/test-company" + When I follow "By position" + Then the first product should have name "product-1" + And the last product should have name "product-9" + + @ui + Scenario: Sorting products by their dates with descending order + Given I am on "/en_US/vendor/test-company" + When I follow "Newest first" + Then the first product should have name "product-30" + And the last product should have name "product-22" + + @ui + Scenario: Sorting products by their dates with ascending order + Given I am on "/en_US/vendor/test-company" + When I follow "Oldest first" + Then the first product should have name "product-1" + And the last product should have name "product-9" + + @ui + Scenario: Sorting products by their prices with ascending order + Given I am on "/en_US/vendor/test-company" + When I follow "Cheapest first" + Then the first product should have name "product-1" + And the last product should have name "product-9" + + @ui + Scenario: Sorting products by their prices with descending order + Given I am on "/en_US/vendor/test-company" + When I follow "Most expensive first" + Then the first product should have name "product-30" + And the last product should have name "product-22" + + @ui + Scenario: Sorting products by their names from a to z + Given I am on "/en_US/vendor/test-company" + When I follow "From A to Z" + Then the first product should have name "product-1" + And the last product should have name "product-17" + + @ui + Scenario: Sorting products by their names from z to a + Given I am on "/en_US/vendor/test-company" + When I follow "From Z to A" + Then the first product should have name "product-9" + And the last product should have name "product-29" diff --git a/OpenMarketplace/package-lock.json b/OpenMarketplace/package-lock.json new file mode 100644 index 0000000..ae22e73 --- /dev/null +++ b/OpenMarketplace/package-lock.json @@ -0,0 +1,28239 @@ +{ + "name": "SyliusMultiVendorMarketplacePlugin", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "license": "MIT", + "dependencies": { + "babel-polyfill": "^6.26.0", + "chart.js": "^2.9.3", + "jquery": "^3.5.0", + "jquery.dirtyforms": "^2.0.0", + "lightbox2": "^2.9.0", + "semantic-ui-css": "^2.2.0", + "slick-carousel": "^1.8.1" + }, + "devDependencies": { + "@symfony/webpack-encore": "^0.28.0", + "babel-core": "^6.26.3", + "babel-plugin-external-helpers": "^6.22.0", + "babel-plugin-module-resolver": "^3.1.1", + "babel-plugin-transform-object-rest-spread": "^6.26.0", + "babel-preset-env": "^1.7.0", + "babel-register": "^6.26.0", + "dedent": "^0.7.0", + "eslint": "^4.19.1", + "eslint-config-airbnb-base": "^12.1.0", + "eslint-import-resolver-babel-module": "^4.0.0", + "eslint-plugin-import": "^2.11.0", + "fast-async": "^6.3.7", + "merge-stream": "^1.0.0", + "node-sass": "^4.14", + "sass-loader": "^7.0.1", + "upath": "^1.1.0", + "yargs": "^6.4.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@ampproject/remapping/node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.3.tgz", + "integrity": "sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", + "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helpers": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/core/node_modules/json5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/core/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/generator": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.3.tgz", + "integrity": "sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.19.3", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", + "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-explode-assignable-expression": "^7.18.6", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", + "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.19.3", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz", + "integrity": "sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", + "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "regexpu-core": "^5.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/regexpu-core": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.1.tgz", + "integrity": "sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsgen": "^0.7.1", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/regjsgen": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", + "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-explode-assignable-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", + "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", + "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", + "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", + "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", + "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-wrap-function": "^7.18.9", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", + "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/traverse": "^7.19.1", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", + "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz", + "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", + "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", + "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-function-name": "^7.19.0", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz", + "integrity": "sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.3.tgz", + "integrity": "sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ==", + "dev": true, + "license": "MIT", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", + "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", + "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-proposal-optional-chaining": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-proposal-async-generator-functions": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz", + "integrity": "sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-static-block": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", + "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-proposal-dynamic-import": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", + "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-export-namespace-from": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-json-strings": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", + "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", + "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz", + "integrity": "sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.18.8", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.18.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-catch-binding": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", + "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", + "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", + "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-unicode-property-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz", + "integrity": "sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "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, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", + "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", + "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-remap-async-to-generator": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", + "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz", + "integrity": "sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz", + "integrity": "sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-compilation-targets": "^7.19.0", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", + "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz", + "integrity": "sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", + "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", + "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", + "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", + "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", + "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", + "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", + "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz", + "integrity": "sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz", + "integrity": "sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz", + "integrity": "sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-validator-identifier": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", + "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", + "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", + "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", + "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz", + "integrity": "sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", + "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", + "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "regenerator-transform": "^0.15.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator/node_modules/regenerator-transform": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", + "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", + "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", + "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", + "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", + "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", + "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", + "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", + "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", + "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.3.tgz", + "integrity": "sha512-ziye1OTc9dGFOAXSWKUqQblYHNlBOaDl8wzqf2iKXJAltYiR3hKHUKmkt+S9PppW7RQpq4fFCrwwpIDj/f5P4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-async-generator-functions": "^7.19.1", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-dynamic-import": "^7.18.6", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", + "@babel/plugin-proposal-json-strings": "^7.18.6", + "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", + "@babel/plugin-proposal-numeric-separator": "^7.18.6", + "@babel/plugin-proposal-object-rest-spread": "^7.18.9", + "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-private-methods": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.18.6", + "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-block-scoped-functions": "^7.18.6", + "@babel/plugin-transform-block-scoping": "^7.18.9", + "@babel/plugin-transform-classes": "^7.19.0", + "@babel/plugin-transform-computed-properties": "^7.18.9", + "@babel/plugin-transform-destructuring": "^7.18.13", + "@babel/plugin-transform-dotall-regex": "^7.18.6", + "@babel/plugin-transform-duplicate-keys": "^7.18.9", + "@babel/plugin-transform-exponentiation-operator": "^7.18.6", + "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-function-name": "^7.18.9", + "@babel/plugin-transform-literals": "^7.18.9", + "@babel/plugin-transform-member-expression-literals": "^7.18.6", + "@babel/plugin-transform-modules-amd": "^7.18.6", + "@babel/plugin-transform-modules-commonjs": "^7.18.6", + "@babel/plugin-transform-modules-systemjs": "^7.19.0", + "@babel/plugin-transform-modules-umd": "^7.18.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", + "@babel/plugin-transform-new-target": "^7.18.6", + "@babel/plugin-transform-object-super": "^7.18.6", + "@babel/plugin-transform-parameters": "^7.18.8", + "@babel/plugin-transform-property-literals": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-reserved-words": "^7.18.6", + "@babel/plugin-transform-shorthand-properties": "^7.18.6", + "@babel/plugin-transform-spread": "^7.19.0", + "@babel/plugin-transform-sticky-regex": "^7.18.6", + "@babel/plugin-transform-template-literals": "^7.18.9", + "@babel/plugin-transform-typeof-symbol": "^7.18.9", + "@babel/plugin-transform-unicode-escapes": "^7.18.10", + "@babel/plugin-transform-unicode-regex": "^7.18.6", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.19.3", + "babel-plugin-polyfill-corejs2": "^0.3.3", + "babel-plugin-polyfill-corejs3": "^0.6.0", + "babel-plugin-polyfill-regenerator": "^0.4.1", + "core-js-compat": "^3.25.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz", + "integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.3.tgz", + "integrity": "sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.19.3", + "@babel/types": "^7.19.3", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/traverse/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/types": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.3.tgz", + "integrity": "sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types/node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", + "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@symfony/webpack-encore": { + "version": "0.28.3", + "resolved": "https://registry.npmjs.org/@symfony/webpack-encore/-/webpack-encore-0.28.3.tgz", + "integrity": "sha512-ZXnwU6uobDCRMbZhT99c42/6j9yIM9aGWgT/we6fdaEGgJJmO1dXl4heq+flL61K3wztQqW6G54N8Q6aPcz1Xw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.4.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/preset-env": "^7.4.0", + "assets-webpack-plugin": "^3.9.7", + "babel-loader": "^8.0.0", + "chalk": "^2.4.1", + "clean-webpack-plugin": "^0.1.19", + "css-loader": "^2.1.1", + "fast-levenshtein": "^2.0.6", + "file-loader": "^1.1.10", + "friendly-errors-webpack-plugin": "^2.0.0-beta.1", + "loader-utils": "^1.1.0", + "mini-css-extract-plugin": ">=0.4.0 <0.4.3", + "optimize-css-assets-webpack-plugin": "^5.0.1", + "pkg-up": "^1.0.0", + "pretty-error": "^2.1.1", + "resolve-url-loader": "^3.0.1", + "semver": "^5.5.0", + "style-loader": "^0.21.0", + "terser-webpack-plugin": "^1.1.0", + "tmp": "^0.0.33", + "webpack": "^4.20.0", + "webpack-cli": "^3.0.0", + "webpack-dev-server": "^3.1.14", + "webpack-manifest-plugin": "^2.0.2", + "webpack-sources": "^1.3.0", + "yargs-parser": "^12.0.0" + }, + "bin": { + "encore": "bin/encore.js" + }, + "engines": { + "node": "8.* || >= 10.*" + } + }, + "node_modules/@symfony/webpack-encore/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", + "dev": true, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@symfony/webpack-encore/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/@symfony/webpack-encore/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/@symfony/webpack-encore/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", + "dev": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@symfony/webpack-encore/node_modules/pkg-up": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "integrity": "sha512-L+d849d9lz20hnRpUnWBRXOh+mAvygQpK7UuXiw+6QbPwL55RVgl+G+V936wCzs/6J7fj0pvgLY9OknZ+FqaNA==", + "dev": true, + "dependencies": { + "find-up": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@symfony/webpack-encore/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.7.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.23.tgz", + "integrity": "sha512-DWNcCHolDq0ZKGizjx2DZjR/PqsYwAcYUJmfMWqtVU2MBMG5Mo+xFZrhGId5r/O5HOuMPyQEcM6KUBp5lBZZBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/q": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", + "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==", + "dev": true + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "dependencies": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "node_modules/@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/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 + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha512-fu2ygVGuMmlzG8ZeRJ0bvR41nsAkxxhbyk8bZ1SS521Z7vmgJFTQQlfz/Mp/nJexGBz+v8sC9bM6+lNgskt4Ug==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-es7-plugin": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/acorn-es7-plugin/-/acorn-es7-plugin-1.1.7.tgz", + "integrity": "sha512-7D+8kscFMf6F2t+8ZRYmv82CncDZETsaZ4dEl5lh3qQez7FVABk2Vz616SAbnIq1PbNsLVaZjl2oSkk5BWAKng==", + "dev": true + }, + "node_modules/acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^3.0.4" + } + }, + "node_modules/acorn-jsx/node_modules/acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz", + "integrity": "sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "node_modules/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, + "peerDependencies": { + "ajv": ">=5.0.0" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ajv-keywords/node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-keywords/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/ajv/node_modules/fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==", + "dev": true, + "license": "MIT" + }, + "node_modules/alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha512-0FcBfdcmaumGPQ0qPn7Q5qTgz/ooXgIyp1rf8ik5bGX8mpE2YHjC0P/eyQvxu1GURYQgq9ozf2mteQ5ZD9YiyQ==", + "dev": true + }, + "node_modules/amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "dev": true, + "engines": { + "node": ">=0.4.2" + } + }, + "node_modules/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, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "license": "ISC", + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "node_modules/are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/arity-n": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz", + "integrity": "sha512-fExL2kFDC1Q2DUOx3whE/9KoN66IzkY4b4zUHUBFM1ojEYjZZYDcUW3bek/ufGionX9giIKDC5redH2IlGqcQQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.reduce": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz", + "integrity": "sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "dependencies": { + "object-assign": "^4.1.1", + "util": "0.10.3" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assert/node_modules/inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==", + "dev": true + }, + "node_modules/assert/node_modules/util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", + "dev": true, + "dependencies": { + "inherits": "2.0.1" + } + }, + "node_modules/assets-webpack-plugin": { + "version": "3.9.12", + "resolved": "https://registry.npmjs.org/assets-webpack-plugin/-/assets-webpack-plugin-3.9.12.tgz", + "integrity": "sha512-iqXT/CtP013CO+IZJG7f4/KmUnde+nn6FSksAhrGRbT1GODsFU3xocP6A5NkTFoey3XOI9n1ZY0QmX/mY74gNA==", + "dev": true, + "dependencies": { + "camelcase": "5.3.1", + "escape-string-regexp": "2.0.0", + "lodash": "4.17.15", + "mkdirp": "0.5.3" + } + }, + "node_modules/assets-webpack-plugin/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/assets-webpack-plugin/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/assets-webpack-plugin/node_modules/lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "node_modules/assets-webpack-plugin/node_modules/mkdirp": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", + "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha512-VUeSMD8nEGBWaZK4lizI1sf3yEC7pnAQ/mrI7pC2fBz2s/tq5jWWEngTwaf0Gruu/OoXRGLGg1XFqpYBiGTYJA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "node_modules/babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "node_modules/babel-code-frame/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", + "dev": true, + "license": "MIT" + }, + "node_modules/babel-code-frame/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/babel-core": { + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + } + }, + "node_modules/babel-core/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + } + }, + "node_modules/babel-generator/node_modules/jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/babel-generator/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/babel-loader": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.5.tgz", + "integrity": "sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^2.0.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + }, + "engines": { + "node": ">= 8.9" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "webpack": ">=2" + } + }, + "node_modules/babel-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/babel-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/babel-loader/node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/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", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-external-helpers": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-external-helpers/-/babel-plugin-external-helpers-6.22.0.tgz", + "integrity": "sha512-TdAMiM6MzLokhk3yCA0KCctmivVZ/mmCwbp7YPmRGkqh2KkcNuxE3R0jxuYU+4xmvfMZx4p4uo8d1cT9t5BLxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-module-resolver": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-3.2.0.tgz", + "integrity": "sha512-tjR0GvSndzPew/Iayf4uICWZqjBwnlMWjSx6brryfQ81F9rxBVqwDJtFCV8oOs0+vJeefK9TmdZtkIFdFe1UnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-babel-config": "^1.1.0", + "glob": "^7.1.2", + "pkg-up": "^2.0.0", + "reselect": "^3.0.1", + "resolve": "^1.4.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.3", + "semver": "^6.1.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", + "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.3", + "core-js-compat": "^3.25.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw==", + "dev": true, + "license": "MIT" + }, + "node_modules/babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha512-C4Aq+GaAj83pRQ0EFgTvw5YO6T3Qz2KGrNRwIj9mSoNHVvdZY4KO2uA6HNtNXCw993iSZnckY1aLW8nOi8i4+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/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, + "license": "MIT", + "dependencies": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "node_modules/babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + } + }, + "node_modules/babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha512-ocgA9VJvyxwt+qJB0ncxV8kb/CjfTcECUY4tQ5VT7nP6Aohzobm8CDFaQ5FHdvZQzLmf0sgDxB8iRXZXxwZcyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + } + }, + "node_modules/babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-transform": "^0.10.0" + } + }, + "node_modules/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": "sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-polyfill": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha512-F2rZGQnAdaHWQ8YAoeRbukc7HS9QgdgeyJ0rQDd485v9opwuPvjpPFcOOT/WmkKTdgy9ESgSPXDcTNpzrGr6iQ==", + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" + } + }, + "node_modules/babel-preset-env": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", + "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^3.2.6", + "invariant": "^2.2.2", + "semver": "^5.3.0" + } + }, + "node_modules/babel-preset-env/node_modules/browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + }, + "bin": { + "browserslist": "cli.js" + } + }, + "node_modules/babel-preset-env/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + } + }, + "node_modules/babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", + "license": "MIT", + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "node_modules/babel-runtime/node_modules/regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "license": "MIT" + }, + "node_modules/babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-traverse/node_modules/globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "node_modules/babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true, + "license": "MIT", + "bin": { + "babylon": "bin/babylon.js" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha512-OorbnJVPII4DuUKbjARAe8u8EfqOmkEEaSFIyoQ7OjTHn6kafxWl0wLgoZ2rXaYd7MyLcDaU4TmhfxtwgcccMQ==", + "dev": true, + "dependencies": { + "inherits": "~2.0.0" + }, + "engines": { + "node": "0.4 || >=0.5.8" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/body-parser/node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha512-RaVTblr+OnEli0r/ud8InrU7D+G0y6aJhlxaLa6Pwty4+xoxboF1BsUI45tujvRpbj9dQVoglChqonGAsjEBYg==", + "dev": true, + "dependencies": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "dependencies": { + "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" + } + }, + "node_modules/browserify-sign/node_modules/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, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "dev": true + }, + "node_modules/cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/cacache/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", + "dev": true, + "dependencies": { + "callsites": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-callsite/node_modules/callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ==", + "dev": true, + "dependencies": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/camelcase-keys/node_modules/camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001414", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001414.tgz", + "integrity": "sha512-t55jfSaWjCdocnFdKQoO+d2ct9C59UZg4dY3OnUlSZ447r8pUtIKdp0hpAzrGFultmTC+Us+KpKi4GZl/LXlFg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/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, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg==", + "dev": true, + "license": "MIT" + }, + "node_modules/chart.js": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz", + "integrity": "sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==", + "license": "MIT", + "dependencies": { + "chartjs-color": "^2.1.0", + "moment": "^2.10.2" + } + }, + "node_modules/chartjs-color": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz", + "integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==", + "license": "MIT", + "dependencies": { + "chartjs-color-string": "^0.6.0", + "color-convert": "^1.9.3" + } + }, + "node_modules/chartjs-color-string": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz", + "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "optional": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "optional": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/chokidar/node_modules/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, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar/node_modules/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, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "optional": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chokidar/node_modules/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, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/chokidar/node_modules/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, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true, + "license": "MIT" + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-webpack-plugin": { + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-0.1.19.tgz", + "integrity": "sha512-M1Li5yLHECcN2MahoreuODul5LkjohJGFxLPTjl3j1ttKrF5rgjZET1SJduuqxLAuT1gAPOdkhg03qcaaU1KeA==", + "dev": true, + "dependencies": { + "rimraf": "^2.6.1" + } + }, + "node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true, + "license": "ISC" + }, + "node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dev": true, + "dependencies": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-convert/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/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==", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dev": true, + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true, + "license": "MIT" + }, + "node_modules/compose-function": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", + "integrity": "sha512-xzhzTJ5eC+gmIzvZq+C3kCJHsp9os6tJkrigDRZclyGtOKINbZtE8n1Tzmeh32jW+BUDPbvZpibwvJHBLGMVwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "arity-n": "^1.0.4" + } + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/convert-source-map/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "dependencies": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "hasInstallScript": true, + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.25.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.3.tgz", + "integrity": "sha512-xVtYpJQ5grszDHEUU9O7XbjjcZ0ccX3LgQsyqSvTnjX97ZqEgn9F5srmrwwwMtbKzDllyFPL+O+2OFMl1lU4TQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.21.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cosmiconfig/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/create-ecdh": { + "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, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/cross-spawn": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "integrity": "sha512-eZ+m1WNhSZutOa/uRblAc9Ut5MQfukFrFMtPSm3bZCA888NmMd5AWXWdgRZ80zd+pTk1P2JrGjg9pUPTvl2PWQ==", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "node_modules/css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha512-zj5D7X1U2h2zsXOAM8EyUREBnnts6H+Jm+d1M2DbiQQcUtnqgQsMrdo8JW9R80YFUmIdBZeMu5wvYM7hcgWP/Q==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.1", + "timsort": "^0.3.0" + }, + "engines": { + "node": ">4" + } + }, + "node_modules/css-loader": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-2.1.1.tgz", + "integrity": "sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w==", + "dev": true, + "dependencies": { + "camelcase": "^5.2.0", + "icss-utils": "^4.1.0", + "loader-utils": "^1.2.3", + "normalize-path": "^3.0.0", + "postcss": "^7.0.14", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^2.0.6", + "postcss-modules-scope": "^2.1.0", + "postcss-modules-values": "^2.0.0", + "postcss-value-parser": "^3.3.0", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/css-loader/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/css-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/css-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "dev": true + }, + "node_modules/css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", + "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", + "dev": true, + "dependencies": { + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.8", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-preset-default": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", + "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", + "dev": true, + "dependencies": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.3", + "postcss-unique-selectors": "^4.0.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha512-6RIcwmV3/cBMG8Aj5gucQRsJb4vv4I4rn6YjPbVWd5+Pn/fuG+YseGvXGk00XLkoZkaj31QOD7vMUpNPC4FIuw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha512-JPMZ1TSMRUPVIqEalIBNoBtAYbi8okvcFns4O0YIhcdGebeYZK7dMyHJiQ6GqNBA9kE0Hym4Aqym5rPdsV/4Cw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==", + "dev": true + }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "license": "ISC", + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true, + "license": "MIT" + }, + "node_modules/deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dev": true, + "dependencies": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/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, + "dependencies": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/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, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/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, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/del/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==", + "dev": true + }, + "node_modules/dns-packet": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", + "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", + "dev": true, + "dependencies": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha512-Ix5PrWjphuSoUXV/Zv5gaFHjnaJtb02F2+Si3Ht9dyJ87+Z/lMmy+dpNHtTGraNK958ndXq2i+GLkWsWHcKaBQ==", + "dev": true, + "dependencies": { + "buffer-indexof": "^1.0.0" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dev": true, + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true, + "engines": { + "node": ">=0.4", + "npm": ">=1.2" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.268", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.268.tgz", + "integrity": "sha512-PO90Bv++vEzdln+eA9qLg1IRnh0rKETus6QkTzcFm5P3Wg3EQBZud5dcnzkpYXuIKWBjKe5CO8zjz02cicvn1g==", + "dev": true, + "license": "ISC" + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/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 + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", + "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/enhanced-resolve/node_modules/memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + }, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "dev": true, + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/es-abstract": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.3.tgz", + "integrity": "sha512-AyrnaKVpMzljIdwjzrj+LxGmj8ik2LckwXacHqrJJ/jxz6dDDBcZ7I7nlHM0FvEW8MfbWJwOd+yT2XzYW49Frw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.6", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.2", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "dev": true, + "hasInstallScript": true, + "license": "ISC", + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "license": "MIT", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", + "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^5.3.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.4", + "esquery": "^1.0.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.0.1", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^1.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", + "table": "4.0.2", + "text-table": "~0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-config-airbnb-base": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz", + "integrity": "sha512-/vjm0Px5ZCpmJqnjIzcFb9TKZrKWz0gnuG/7Gfkt0Db1ELJR51xkZth+t14rYdqWgX836XbuxtArbIHlVhbLBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-restricted-globals": "^0.1.1" + }, + "engines": { + "node": ">= 4" + }, + "peerDependencies": { + "eslint": "^4.9.0", + "eslint-plugin-import": "^2.7.0" + } + }, + "node_modules/eslint-import-resolver-babel-module": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-babel-module/-/eslint-import-resolver-babel-module-4.0.0.tgz", + "integrity": "sha512-aPj0+pG0H3HCaMD9eRDYEzPdMyKrLE2oNhAzTXd2w86ZBe3s7drSrrPwVTfzO1CBp13FGk8S84oRmZHZvSo0mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-up": "^2.0.0", + "resolve": "^1.4.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "babel-core": "^6.0.0", + "babel-plugin-module-resolver": "^3.0.0-beta" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-restricted-globals": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", + "integrity": "sha512-d1cerYC0nOJbObxUe1kR8MZ25RLt7IHzR9d+IOupoMqFU03tYjo7Stjqj04uHx1xx7HKSE9/NjdeBiP4/jUP8Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-scope": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/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, + "license": "Apache-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/eslint/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/espree/node_modules/acorn": { + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/eventsource": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", + "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/execa/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/express": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", + "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.0", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.10.3", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/express/node_modules/qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "license": "ISC", + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true, + "license": "ISC" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-async": { + "version": "6.3.8", + "resolved": "https://registry.npmjs.org/fast-async/-/fast-async-6.3.8.tgz", + "integrity": "sha512-TjlooyqrYm/gOXjD2UHNwfrWkvTbzU105Nk4bvcRTeRoL+wIeK6rqbqDg3CN9z5p37cE2iXhP6SxQFz8OVIaUg==", + "dev": true, + "dependencies": { + "nodent-compiler": "^3.2.10", + "nodent-runtime": ">=3.2.1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/file-loader": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", + "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==", + "dev": true, + "dependencies": { + "loader-utils": "^1.0.2", + "schema-utils": "^0.4.5" + }, + "engines": { + "node": ">= 4.3 < 5.0.0 || >= 5.10" + }, + "peerDependencies": { + "webpack": "^2.0.0 || ^3.0.0 || ^4.0.0" + } + }, + "node_modules/file-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/file-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/file-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/file-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", + "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/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, + "license": "MIT", + "dependencies": { + "json5": "^0.5.1", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "dev": true, + "license": "MIT", + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/friendly-errors-webpack-plugin": { + "version": "2.0.0-beta.2", + "resolved": "https://registry.npmjs.org/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-2.0.0-beta.2.tgz", + "integrity": "sha512-0x14cdjGx5q0yZc3Cy9sgAF/szWUFx1WxH/IX88UuKbM5Z+7FCk/Z/6hFbXMcz3qqK0mp7WrHKX3cxhUAL2aqQ==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "error-stack-parser": "^2.0.2", + "string-width": "^2.0.0", + "strip-ansi": "^5" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/friendly-errors-webpack-plugin/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/friendly-errors-webpack-plugin/node_modules/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, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/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, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", + "dev": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "dev": true, + "dependencies": { + "globule": "^1.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "node_modules/get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/get-stream/node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/globule": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz", + "integrity": "sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg==", + "dev": true, + "dependencies": { + "glob": "~7.1.1", + "lodash": "^4.17.21", + "minimatch": "~3.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/globule/node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globule/node_modules/minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true, + "license": "ISC" + }, + "node_modules/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 + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/har-validator/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/har-validator/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash-base/node_modules/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, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/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, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/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 + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha512-M5ezZw4LzXbBKMruP+BNANf0k+19hDQMgpzBIYnya//Al+fjNct9Wf3b1WedLqdEs2hKBvxq/jh+DsHJLj0F9A==", + "dev": true + }, + "node_modules/hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha512-7Wn5GMLuHBjZCb2bTmnDOycho0p/7UVaAeqXZGbHrBCl6Yd/xDhQJAXe6Ga9AXJH2I5zY1dEdYw2u1UptnSBJA==", + "dev": true + }, + "node_modules/html-entities": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", + "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==", + "dev": true + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/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, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/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, + "dependencies": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", + "dev": true + }, + "node_modules/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, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==", + "dev": true + }, + "node_modules/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, + "dependencies": { + "postcss": "^7.0.14" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==", + "dev": true + }, + "node_modules/ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true, + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "dev": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-fresh/node_modules/caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", + "dev": true, + "dependencies": { + "caller-callsite": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/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, + "dependencies": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local/node_modules/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, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local/node_modules/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, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local/node_modules/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, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local/node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/in-publish": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz", + "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==", + "dev": true, + "bin": { + "in-install": "in-install.js", + "in-publish": "in-publish.js", + "not-in-install": "not-in-install.js", + "not-in-publish": "not-in-publish.js" + } + }, + "node_modules/indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg==", + "dev": true, + "dependencies": { + "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==", + "dev": true + }, + "node_modules/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 + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + } + }, + "node_modules/inquirer/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/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, + "dependencies": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ip": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", + "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", + "dev": true + }, + "node_modules/ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/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, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha512-vOx7VprsKyllwjSkLV79NIhpyLfr3jAp7VaTCMXOJHu4m0Ew1CZ2fcjASwmV1jI3BWuWHB013M48eyeldk9gYg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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, + "license": "MIT" + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha512-H1U8Vz0cfXNujrJzEcvvwMDW9Ra+biSYA3ThdQvAnMLJkEHQXn6bWzLkxHtVYJ+Sdbx0b6finn3jZiaVe7MAHA==", + "dev": true, + "dependencies": { + "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" + } + }, + "node_modules/is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/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, + "engines": { + "node": ">=6" + } + }, + "node_modules/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, + "dependencies": { + "is-path-inside": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/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, + "dependencies": { + "path-is-inside": "^1.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/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, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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, + "license": "ISC" + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, + "node_modules/jquery": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz", + "integrity": "sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw==", + "license": "MIT" + }, + "node_modules/jquery.dirtyforms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jquery.dirtyforms/-/jquery.dirtyforms-2.0.0.tgz", + "integrity": "sha512-iGhN+ESRCYgR1Tz3Z5RwKhCZi+1LMQiglHxghtTk10O1KmjvZwd2HUrSsV9Zn3ntFgDzYcQcLNERUAAF4RDT/A==", + "license": "MIT", + "dependencies": { + "jquery": ">=1.4.2" + } + }, + "node_modules/js-base64": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, + "node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "node_modules/json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/last-call-webpack-plugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", + "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", + "dev": true, + "dependencies": { + "lodash": "^4.17.5", + "webpack-sources": "^1.1.0" + } + }, + "node_modules/lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "invert-kv": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightbox2": { + "version": "2.11.3", + "resolved": "https://registry.npmjs.org/lightbox2/-/lightbox2-2.11.3.tgz", + "integrity": "sha512-Q4v6il/OK9ttgEkAxSok/jrI/LUbqTrePFchqP2x/59qaDIZgJjEEc5Xf7peSMc/55Zo5PAgmX6EiN/BeEeUBQ==" + }, + "node_modules/load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/loader-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", + "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/loader-utils/node_modules/json5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "node_modules/loglevel": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz", + "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==", + "dev": true, + "dependencies": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "license": "ISC", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/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, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "node_modules/meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA==", + "dev": true, + "dependencies": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "node_modules/merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha512-e6RM36aegd4f+r8BZCcYXlO2P3H6xbUM6ktL2Xmf45GAOit9bI4z6/3VU7JwllVO1L7u0UDSg/EhzQ5lmMLolA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.1" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.2.tgz", + "integrity": "sha512-ots7URQH4wccfJq9Ssrzu2+qupbncAce4TmTzunI9CIwlQMp2XI+WNUw6xWF6MMAGAm1cbUVINrSjATaVMyKXg==", + "dev": true, + "dependencies": { + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" + }, + "engines": { + "node": ">= 6.9.0 <7.0.0 || >= 8.9.0" + }, + "peerDependencies": { + "webpack": "^4.4.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "dependencies": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mississippi/node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==", + "dev": true, + "dependencies": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dev": true, + "dependencies": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha512-cnAsSVxIDsYt0v7HmC0hWZFwwXSh+E6PgCrREDuN/EsjgLwA5XRmlMHhSiDPrt6HxY1gTivEa/Zh7GtODoLevQ==", + "dev": true + }, + "node_modules/mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/nan": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", + "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", + "dev": true + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "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, + "license": "MIT" + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "dev": true, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/node-gyp": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", + "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", + "dev": true, + "dependencies": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/node-gyp/node_modules/semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha512-mfmm3/H9+67MCVix1h+IXTpDwL6710LyHuk7+cWC9T1mE0qz4iHhh6r4hU2wrIT9iTsAAC2XQRvfblL028cpLw==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "dependencies": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + } + }, + "node_modules/node-libs-browser/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-sass": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz", + "integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^3.0.0", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "in-publish": "^2.0.0", + "lodash": "^4.17.15", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.13.2", + "node-gyp": "^3.8.0", + "npmlog": "^4.0.0", + "request": "^2.88.0", + "sass-graph": "2.2.5", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" + }, + "bin": { + "node-sass": "bin/node-sass" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-sass/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-sass/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/nodent-compiler": { + "version": "3.2.13", + "resolved": "https://registry.npmjs.org/nodent-compiler/-/nodent-compiler-3.2.13.tgz", + "integrity": "sha512-nzzWPXZwSdsWie34om+4dLrT/5l1nT/+ig1v06xuSgMtieJVAnMQFuZihUwREM+M7dFso9YoHfDmweexEXXrrw==", + "dev": true, + "engines": "node >= 0.10.0", + "dependencies": { + "acorn": ">= 2.5.2 <= 5.7.5", + "acorn-es7-plugin": "^1.1.7", + "nodent-transform": "^3.2.9", + "source-map": "^0.5.7" + } + }, + "node_modules/nodent-compiler/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nodent-runtime": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/nodent-runtime/-/nodent-runtime-3.2.1.tgz", + "integrity": "sha512-7Ws63oC+215smeKJQCxzrK21VFVlCFBkwl0MOObt0HOpVQXs3u483sAmtkF33nNqZ5rSOQjB76fgyPBmAUrtCA==", + "dev": true, + "hasInstallScript": true + }, + "node_modules/nodent-transform": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/nodent-transform/-/nodent-transform-3.2.9.tgz", + "integrity": "sha512-4a5FH4WLi+daH/CGD5o/JWRR8W5tlCkd3nrDSkxbOzscJTyTUITltvOJeQjg3HJ1YgEuNyiPhQbvbtRjkQBByQ==", + "dev": true + }, + "node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz", + "integrity": "sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==", + "dev": true, + "dependencies": { + "array.prototype.reduce": "^1.0.4", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dev": true, + "dependencies": { + "is-wsl": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/optimize-css-assets-webpack-plugin": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.8.tgz", + "integrity": "sha512-mgFS1JdOtEGzD8l+EuISqL57cKO+We9GcoiQEmdCWRqqck+FGNmYJtx9qfAPzEz+lRrlThWMuGDaRkI/yWNx/Q==", + "dev": true, + "dependencies": { + "cssnano": "^4.1.10", + "last-call-webpack-plugin": "^3.0.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", + "dev": true + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "lcid": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/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, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/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, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "dev": true, + "dependencies": { + "retry": "^0.12.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/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, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "node_modules/parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "dependencies": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "node_modules/parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true, + "license": "(WTFPL OR MIT)" + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha512-fjAPuiws93rm7mPUu21RdBnkeZNrbfCFCwfAhPWY+rR3zG0ubpe5cEReHOw5fIbfmsxEV/g2kSxGTATY3Bpnwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/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, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", + "dev": true, + "dependencies": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-calc": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", + "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", + "dev": true, + "dependencies": { + "postcss": "^7.0.27", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/postcss-calc/node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/postcss-colormin": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", + "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-comments": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", + "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", + "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "dev": true, + "dependencies": { + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-merge-rules": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", + "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", + "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "dev": true, + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-params": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", + "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", + "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz", + "integrity": "sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0", + "postcss-value-parser": "^3.3.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-values": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz", + "integrity": "sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w==", + "dev": true, + "dependencies": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^7.0.6" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", + "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "dev": true, + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", + "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "dev": true, + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", + "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "dev": true, + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-string": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", + "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "dev": true, + "dependencies": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", + "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "dev": true, + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "dev": true, + "dependencies": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", + "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-ordered-values": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", + "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "dev": true, + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", + "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", + "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "dev": true, + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", + "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pretty-error": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", + "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^2.0.4" + } + }, + "node_modules/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, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "optional": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g==", + "dev": true, + "dependencies": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha512-02YopEIhAgiBHWeoTiA8aitHDt8z6w+rQqNuIftlM+ZtvSl/brTouaU7DW6GO/cHtvxJvS4Hwv2ibKdxIRi24w==", + "license": "MIT" + }, + "node_modules/regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "dev": true, + "license": "BSD", + "dependencies": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-parser": { + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", + "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", + "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "node_modules/regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g==", + "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw==", + "dev": true, + "license": "BSD", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true, + "license": "ISC" + }, + "node_modules/renderkid": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.7.tgz", + "integrity": "sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==", + "dev": true, + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^3.0.1" + } + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-finite": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", + "dev": true, + "license": "ISC" + }, + "node_modules/require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/reselect": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-3.0.1.tgz", + "integrity": "sha512-b/6tFZCmRhtBMa4xGqiiRp9jh9Aqi2A687Lo265cN0/QohJQEBPiQ52f4QB6i0eF3yp3hmLL21LSGBcML2dlxA==", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg==", + "dev": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve-url-loader": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.4.tgz", + "integrity": "sha512-D3sQ04o0eeQEySLrcz4DsX3saHfsr8/N6tfhblxgZKXxMT2Louargg12oGNfoTRLV09GXhVUe5/qgA5vdgNigg==", + "dev": true, + "license": "MIT", + "dependencies": { + "adjust-sourcemap-loader": "3.0.0", + "camelcase": "5.3.1", + "compose-function": "3.0.3", + "convert-source-map": "1.7.0", + "es6-iterator": "2.0.3", + "loader-utils": "1.2.3", + "postcss": "7.0.36", + "rework": "1.0.1", + "rework-visit": "1.0.0", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/resolve-url-loader/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/resolve-url-loader/node_modules/convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/resolve-url-loader/node_modules/emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/resolve-url-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/resolve-url-loader/node_modules/loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/resolve-url-loader/node_modules/postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/resolve-url-loader/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/rework": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz", + "integrity": "sha512-eEjL8FdkdsxApd0yWVZgBGzfCQiT8yqSc2H1p4jpZpQdtz7ohETiDMoje5PlM8I9WgkqkreVxFUKYOiJdVWDXw==", + "dev": true, + "dependencies": { + "convert-source-map": "^0.3.3", + "css": "^2.0.0" + } + }, + "node_modules/rework-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz", + "integrity": "sha512-W6V2fix7nCLUYX1v6eGPrBOZlc03/faqzP4sUxMAJMBMOPYhfV/RyLegTufn5gJKaOITyi+gvf0LXDZ9NzkHnQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/rework/node_modules/convert-source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", + "integrity": "sha512-+4nRk0k3oEpwUB7/CalD7xE2z4VmtEnnq0GO2IPTkrooTrAhEsWvuLF5iWP1dXrwluki/azwXV1ve7gtYuPldg==", + "dev": true, + "license": "MIT" + }, + "node_modules/rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha512-gDK5mkALDFER2YLqH6imYvK6g02gpNGM4ILDZ472EwWfXZnC2ZEpoB2ECXTyOVUKuk/bPJZMzwQPBYICzP+D3w==", + "dev": true + }, + "node_modules/rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha512-zgn5OjNQXLUTdq8m17KdaicF6w89TZs8ZU8y0AYENIU6wG8GG6LLm0yLSiPY8DmaYmHdgRW8rnApjoT0fQRfMg==", + "dev": true + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==", + "dev": true, + "dependencies": { + "aproba": "^1.1.1" + } + }, + "node_modules/rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha512-Cun9QucwK6MIrp3mry/Y7hqD1oFqTYLQ4pGxaHTjIdaFDWRGGLikqp6u8LcWJnzpoALg9hap+JGk8sFIUuEGNA==", + "dev": true + }, + "node_modules/rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha512-3xPNZGW93oCjiO7PtKxRK6iOVYBWBvtf9QHDfU23Oc+dLIQmAV//UnyXV/yihv81VS/UqoQPk4NegS8EFi55Hg==", + "dev": true, + "dependencies": { + "rx-lite": "*" + } + }, + "node_modules/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, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sass-graph": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz", + "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==", + "dev": true, + "dependencies": { + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^13.3.2" + }, + "bin": { + "sassgraph": "bin/sassgraph" + } + }, + "node_modules/sass-graph/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/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, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sass-graph/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/sass-graph/node_modules/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, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/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, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/sass-graph/node_modules/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, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/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, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/sass-graph/node_modules/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, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/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, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "dev": true + }, + "node_modules/sass-graph/node_modules/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, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "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" + } + }, + "node_modules/sass-graph/node_modules/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, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/sass-loader": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.3.1.tgz", + "integrity": "sha512-tuU7+zm0pTCynKYHpdqaPpe+MMTQ76I9TPZ7i4/5dZsigE350shQWe5EZNl5dBidM49TPET75tNqRbcsUZWeNA==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "loader-utils": "^1.0.1", + "neo-async": "^2.5.0", + "pify": "^4.0.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^3.0.0 || ^4.0.0" + } + }, + "node_modules/sass-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/sass-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/sass-loader/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "node_modules/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, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/schema-utils/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha512-dYE8LhncfBUar6POCxMTm0Ln+erjeczqEvCJib5/7XNkdw1FkUGgwMPY360FY0FgPWQxHWCx29Jl3oejyGLM9Q==", + "dev": true, + "dependencies": { + "js-base64": "^2.1.8", + "source-map": "^0.4.2" + } + }, + "node_modules/scss-tokenizer/node_modules/source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha512-Y8nIfcb1s/7DcobUz1yOO1GSp7gyL+D9zLHDehT7iRESqGSxjJ448Sg7rvfgsRJCnKLdSl11uGf0s9X80cH0/A==", + "dev": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true + }, + "node_modules/selfsigned": { + "version": "1.10.14", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.14.tgz", + "integrity": "sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA==", + "dev": true, + "dependencies": { + "node-forge": "^0.10.0" + } + }, + "node_modules/semantic-ui-css": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/semantic-ui-css/-/semantic-ui-css-2.4.1.tgz", + "integrity": "sha512-Pkp0p9oWOxlH0kODx7qFpIRYpK1T4WJOO4lNnpNPOoWKCrYsfHqYSKgk5fHfQtnWnsAKy7nLJMW02bgDWWFZFg==", + "license": "MIT", + "dependencies": { + "jquery": "x.*" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true, + "license": "ISC" + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/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, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true + }, + "node_modules/slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/slick-carousel": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz", + "integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA==", + "license": "MIT", + "peerDependencies": { + "jquery": ">=1.8.0" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "license": "MIT", + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sockjs-client": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.6.1.tgz", + "integrity": "sha512-2g0tjOR+fRs0amxENLi/q5TiJTqY+WXFOzb5UwXndlK6TO3U/mirZznpx6w34HVMoc3g7cY24yC/ZMIYnDlfkw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "eventsource": "^2.0.2", + "faye-websocket": "^0.11.4", + "inherits": "^2.0.4", + "url-parse": "^1.5.10" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://tidelift.com/funding/github/npm/sockjs-client" + } + }, + "node_modules/sockjs-client/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/sockjs-client/node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/sockjs/node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/sockjs/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "node_modules/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, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map": "^0.5.6" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "dev": true, + "license": "MIT" + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/spdy-transport/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/spdy-transport/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/spdy-transport/node_modules/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, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/spdy/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/spdy/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ssri": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", + "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", + "dev": true, + "dependencies": { + "figgy-pudding": "^3.5.1" + } + }, + "node_modules/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", + "dev": true + }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", + "dev": true + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stdout-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", + "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.1" + } + }, + "node_modules/stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "dependencies": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/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, + "license": "MIT" + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA==", + "dev": true, + "dependencies": { + "get-stdin": "^4.0.1" + }, + "bin": { + "strip-indent": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/style-loader": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.21.0.tgz", + "integrity": "sha512-T+UNsAcl3Yg+BsPKs1vd22Fr8sVT+CJMtzqc6LEw9bbJZb43lm9GoeIfUcDEefBSWC0BhYbcdupV1GtI4DGzxg==", + "dev": true, + "dependencies": { + "loader-utils": "^1.1.0", + "schema-utils": "^0.4.5" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/style-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/style-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/style-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/style-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/style-loader/node_modules/schema-utils": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", + "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/stylehacks": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", + "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/stylehacks/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/svgo/node_modules/css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "node_modules/svgo/node_modules/css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/svgo/node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/svgo/node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/svgo/node_modules/domutils/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "node_modules/svgo/node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/table": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "ajv": "^5.2.3", + "ajv-keywords": "^2.1.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + } + }, + "node_modules/table/node_modules/ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha512-ZFztHzVRdGLAzJmpUT9LNFLe1YiVOEylcaNpEutM26PVTCtOD919IMfD01CgbRouB42Dd9atjx1HseC15DgOZA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^5.0.0" + } + }, + "node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", + "deprecated": "This version of tar is no longer supported, and will not receive security updates. Please upgrade asap.", + "dev": true, + "dependencies": { + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" + } + }, + "node_modules/terser": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", + "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==", + "dev": true, + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/terser-webpack-plugin": { + "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, + "dependencies": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/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, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/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, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/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, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/terser/node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dev": true, + "dependencies": { + "setimmediate": "^1.0.4" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", + "dev": true + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/true-case-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", + "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", + "dev": true, + "dependencies": { + "glob": "^7.1.2" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true, + "license": "ISC" + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", + "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==", + "dev": true + }, + "node_modules/uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha512-mZdDpf3vBV5Efh29kMw5tXoup/buMgxLzOt/XKFKcVmi+15ManNQWr6HfZ2aiZTYlYixbdNJ0KFmIZIv52tHSQ==", + "dev": true + }, + "node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==", + "dev": true + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz", + "integrity": "sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "dev": true, + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "dev": true + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "dependencies": { + "inherits": "2.0.3" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/util/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vendors": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", + "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, + "node_modules/vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "node_modules/watchpack": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", + "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + }, + "optionalDependencies": { + "chokidar": "^3.4.1", + "watchpack-chokidar2": "^2.0.1" + } + }, + "node_modules/watchpack-chokidar2": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", + "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", + "dev": true, + "optional": true, + "dependencies": { + "chokidar": "^2.1.8" + } + }, + "node_modules/watchpack-chokidar2/node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", + "dev": true, + "optional": true, + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/watchpack-chokidar2/node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", + "dev": true, + "optional": true, + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "optional": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/webpack": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", + "integrity": "sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.5.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.7.4", + "webpack-sources": "^1.4.1" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + }, + "webpack-command": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz", + "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "enhanced-resolve": "^4.1.1", + "findup-sync": "^3.0.0", + "global-modules": "^2.0.0", + "import-local": "^2.0.0", + "interpret": "^1.4.0", + "loader-utils": "^1.4.0", + "supports-color": "^6.1.0", + "v8-compile-cache": "^2.1.1", + "yargs": "^13.3.2" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=6.11.5" + }, + "peerDependencies": { + "webpack": "4.x.x" + } + }, + "node_modules/webpack-cli/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/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, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack-cli/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/webpack-cli/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/webpack-cli/node_modules/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, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/webpack-cli/node_modules/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, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/webpack-cli/node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/webpack-cli/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/webpack-cli/node_modules/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, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/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, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/webpack-cli/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/webpack-cli/node_modules/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, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/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, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "dev": true + }, + "node_modules/webpack-cli/node_modules/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, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "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" + } + }, + "node_modules/webpack-cli/node_modules/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, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz", + "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==", + "dev": true, + "dependencies": { + "memory-fs": "^0.4.1", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/webpack-dev-server": { + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.3.tgz", + "integrity": "sha512-3x31rjbEQWKMNzacUZRE6wXvUFuGpH7vr0lIEbYpMAG9BOxi0928QU1BBswOAP3kg3H1O4hiS+sq4YyAn6ANnA==", + "dev": true, + "dependencies": { + "ansi-html-community": "0.0.8", + "bonjour": "^3.5.0", + "chokidar": "^2.1.8", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.3.1", + "http-proxy-middleware": "0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", + "killable": "^1.0.1", + "loglevel": "^1.6.8", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.26", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.8", + "semver": "^6.3.0", + "serve-index": "^1.9.1", + "sockjs": "^0.3.21", + "sockjs-client": "^1.5.0", + "spdy": "^4.0.2", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.2", + "webpack-log": "^2.0.0", + "ws": "^6.2.1", + "yargs": "^13.3.2" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 6.11.5" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/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, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack-dev-server/node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", + "dev": true, + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/webpack-dev-server/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/webpack-dev-server/node_modules/cliui/node_modules/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, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/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, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/webpack-dev-server/node_modules/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, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/webpack-dev-server/node_modules/is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack-dev-server/node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", + "dev": true, + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/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, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/webpack-dev-server/node_modules/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, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/webpack-dev-server/node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/webpack-dev-server/node_modules/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, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/string-width/node_modules/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, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "dev": true + }, + "node_modules/webpack-dev-server/node_modules/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, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/wrap-ansi/node_modules/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, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "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" + } + }, + "node_modules/webpack-dev-server/node_modules/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, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "dependencies": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/webpack-log/node_modules/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, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-manifest-plugin": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-2.2.0.tgz", + "integrity": "sha512-9S6YyKKKh/Oz/eryM1RyLVDVmy3NSPV0JXMRhZ18fJsq+AwGxUY34X54VNwkzYcEmEkDwNxuEOboCZEebJXBAQ==", + "dev": true, + "dependencies": { + "fs-extra": "^7.0.0", + "lodash": ">=3.5 <5", + "object.entries": "^1.1.0", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=6.11.5" + }, + "peerDependencies": { + "webpack": "2 || 3 || 4" + } + }, + "node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "node_modules/webpack/node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/webpack/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/webpack/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "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, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "dependencies": { + "errno": "~0.1.7" + } + }, + "node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha512-CJ17OoULEKXpA5pef3qLj5AxTJ6mSt7g84he2WIskKwqFO4T97d5V7Tadl0DYDk7qyUOQD5WlUlOMChaYrhxeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", + "integrity": "sha512-6/QWTdisjnu5UHUzQGst+UOEuEVwIzFVGBjq3jMTFNs5WJQsH/X6nMURSaScIdF5txylr1Ao9bvbWiKi2yXbwA==", + "dev": true, + "dependencies": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^4.2.0" + } + }, + "node_modules/yargs-parser": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-12.0.0.tgz", + "integrity": "sha512-WQM8GrbF5TKiACr7iE3I2ZBNC7qC9taKPMfjJaMD2LkOJQhIctASxKXdFAOPim/m47kgAQBVIaPlFjnRdkol7w==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/yargs-parser/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs/node_modules/y18n": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", + "dev": true + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "integrity": "sha512-+QQWqC2xeL0N5/TE+TY6OGEqyNRM+g2/r712PDNYgiCdXYCApXf1vzfmDSLBxfGRwV+moTq/V8FnMI24JCm2Yg==", + "dev": true, + "dependencies": { + "camelcase": "^3.0.0" + } + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } + } + }, + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/compat-data": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.3.tgz", + "integrity": "sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw==", + "dev": true + }, + "@babel/core": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", + "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helpers": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "json5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.3.tgz", + "integrity": "sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==", + "dev": true, + "requires": { + "@babel/types": "^7.19.3", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "dependencies": { + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", + "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.18.6", + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", + "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.19.3", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz", + "integrity": "sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", + "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "regexpu-core": "^5.1.0" + }, + "dependencies": { + "regexpu-core": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.1.tgz", + "integrity": "sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsgen": "^0.7.1", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.0.0" + } + }, + "regjsgen": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", + "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", + "dev": true + }, + "regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + } + } + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", + "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "dev": true, + "requires": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", + "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "dev": true, + "requires": { + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-transforms": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", + "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", + "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", + "dev": true + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", + "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-wrap-function": "^7.18.9", + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-replace-supers": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", + "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/traverse": "^7.19.1", + "@babel/types": "^7.19.0" + } + }, + "@babel/helper-simple-access": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", + "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz", + "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==", + "dev": true, + "requires": { + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", + "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "dev": true + }, + "@babel/helper-wrap-function": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", + "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.19.0", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" + } + }, + "@babel/helpers": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz", + "integrity": "sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==", + "dev": true, + "requires": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.3.tgz", + "integrity": "sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ==", + "dev": true + }, + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", + "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", + "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-proposal-optional-chaining": "^7.18.9" + } + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz", + "integrity": "sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-proposal-class-static-block": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", + "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", + "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + } + }, + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", + "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3" + } + }, + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", + "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz", + "integrity": "sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.18.8", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.18.8" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", + "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", + "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", + "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@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-import-assertions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz", + "integrity": "sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@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", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@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": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "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.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", + "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", + "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-remap-async-to-generator": "^7.18.6" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", + "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz", + "integrity": "sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz", + "integrity": "sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-compilation-targets": "^7.19.0", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", + "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz", + "integrity": "sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", + "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", + "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", + "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", + "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", + "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", + "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", + "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz", + "integrity": "sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz", + "integrity": "sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz", + "integrity": "sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-validator-identifier": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", + "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", + "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", + "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", + "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.6" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz", + "integrity": "sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", + "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", + "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "regenerator-transform": "^0.15.0" + }, + "dependencies": { + "regenerator-transform": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", + "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.4" + } + } + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", + "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", + "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", + "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", + "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", + "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", + "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", + "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", + "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/preset-env": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.3.tgz", + "integrity": "sha512-ziye1OTc9dGFOAXSWKUqQblYHNlBOaDl8wzqf2iKXJAltYiR3hKHUKmkt+S9PppW7RQpq4fFCrwwpIDj/f5P4w==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-async-generator-functions": "^7.19.1", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-dynamic-import": "^7.18.6", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", + "@babel/plugin-proposal-json-strings": "^7.18.6", + "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", + "@babel/plugin-proposal-numeric-separator": "^7.18.6", + "@babel/plugin-proposal-object-rest-spread": "^7.18.9", + "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-private-methods": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.18.6", + "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-block-scoped-functions": "^7.18.6", + "@babel/plugin-transform-block-scoping": "^7.18.9", + "@babel/plugin-transform-classes": "^7.19.0", + "@babel/plugin-transform-computed-properties": "^7.18.9", + "@babel/plugin-transform-destructuring": "^7.18.13", + "@babel/plugin-transform-dotall-regex": "^7.18.6", + "@babel/plugin-transform-duplicate-keys": "^7.18.9", + "@babel/plugin-transform-exponentiation-operator": "^7.18.6", + "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-function-name": "^7.18.9", + "@babel/plugin-transform-literals": "^7.18.9", + "@babel/plugin-transform-member-expression-literals": "^7.18.6", + "@babel/plugin-transform-modules-amd": "^7.18.6", + "@babel/plugin-transform-modules-commonjs": "^7.18.6", + "@babel/plugin-transform-modules-systemjs": "^7.19.0", + "@babel/plugin-transform-modules-umd": "^7.18.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", + "@babel/plugin-transform-new-target": "^7.18.6", + "@babel/plugin-transform-object-super": "^7.18.6", + "@babel/plugin-transform-parameters": "^7.18.8", + "@babel/plugin-transform-property-literals": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-reserved-words": "^7.18.6", + "@babel/plugin-transform-shorthand-properties": "^7.18.6", + "@babel/plugin-transform-spread": "^7.19.0", + "@babel/plugin-transform-sticky-regex": "^7.18.6", + "@babel/plugin-transform-template-literals": "^7.18.9", + "@babel/plugin-transform-typeof-symbol": "^7.18.9", + "@babel/plugin-transform-unicode-escapes": "^7.18.10", + "@babel/plugin-transform-unicode-regex": "^7.18.6", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.19.3", + "babel-plugin-polyfill-corejs2": "^0.3.3", + "babel-plugin-polyfill-corejs3": "^0.6.0", + "babel-plugin-polyfill-regenerator": "^0.4.1", + "core-js-compat": "^3.25.1", + "semver": "^6.3.0" + } + }, + "@babel/preset-modules": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/runtime": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz", + "integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "dev": true + } + } + }, + "@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + } + }, + "@babel/traverse": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.3.tgz", + "integrity": "sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.19.3", + "@babel/types": "^7.19.3", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.3.tgz", + "integrity": "sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true + } + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", + "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@symfony/webpack-encore": { + "version": "0.28.3", + "resolved": "https://registry.npmjs.org/@symfony/webpack-encore/-/webpack-encore-0.28.3.tgz", + "integrity": "sha512-ZXnwU6uobDCRMbZhT99c42/6j9yIM9aGWgT/we6fdaEGgJJmO1dXl4heq+flL61K3wztQqW6G54N8Q6aPcz1Xw==", + "dev": true, + "requires": { + "@babel/core": "^7.4.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/preset-env": "^7.4.0", + "assets-webpack-plugin": "^3.9.7", + "babel-loader": "^8.0.0", + "chalk": "^2.4.1", + "clean-webpack-plugin": "^0.1.19", + "css-loader": "^2.1.1", + "fast-levenshtein": "^2.0.6", + "file-loader": "^1.1.10", + "friendly-errors-webpack-plugin": "^2.0.0-beta.1", + "loader-utils": "^1.1.0", + "mini-css-extract-plugin": ">=0.4.0 <0.4.3", + "optimize-css-assets-webpack-plugin": "^5.0.1", + "pkg-up": "^1.0.0", + "pretty-error": "^2.1.1", + "resolve-url-loader": "^3.0.1", + "semver": "^5.5.0", + "style-loader": "^0.21.0", + "terser-webpack-plugin": "^1.1.0", + "tmp": "^0.0.33", + "webpack": "^4.20.0", + "webpack-cli": "^3.0.0", + "webpack-dev-server": "^3.1.14", + "webpack-manifest-plugin": "^2.0.2", + "webpack-sources": "^1.3.0", + "yargs-parser": "^12.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "pkg-up": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "integrity": "sha512-L+d849d9lz20hnRpUnWBRXOh+mAvygQpK7UuXiw+6QbPwL55RVgl+G+V936wCzs/6J7fj0pvgLY9OknZ+FqaNA==", + "dev": true, + "requires": { + "find-up": "^1.0.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true + }, + "@types/node": { + "version": "18.7.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.23.tgz", + "integrity": "sha512-DWNcCHolDq0ZKGizjx2DZjR/PqsYwAcYUJmfMWqtVU2MBMG5Mo+xFZrhGId5r/O5HOuMPyQEcM6KUBp5lBZZBg==", + "dev": true + }, + "@types/q": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", + "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==", + "dev": true + }, + "@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "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.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha512-fu2ygVGuMmlzG8ZeRJ0bvR41nsAkxxhbyk8bZ1SS521Z7vmgJFTQQlfz/Mp/nJexGBz+v8sC9bM6+lNgskt4Ug==", + "dev": true + }, + "acorn-es7-plugin": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/acorn-es7-plugin/-/acorn-es7-plugin-1.1.7.tgz", + "integrity": "sha512-7D+8kscFMf6F2t+8ZRYmv82CncDZETsaZ4dEl5lh3qQez7FVABk2Vz616SAbnIq1PbNsLVaZjl2oSkk5BWAKng==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==", + "dev": true, + "requires": { + "acorn": "^3.0.4" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", + "dev": true + } + } + }, + "adjust-sourcemap-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz", + "integrity": "sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + } + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==", + "dev": true, + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + }, + "dependencies": { + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==", + "dev": true + } + } + }, + "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, + "requires": {} + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "requires": {}, + "dependencies": { + "ajv": { + "version": "6.12.6", + "dev": true, + "peer": 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" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "peer": true + } + } + }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha512-0FcBfdcmaumGPQ0qPn7Q5qTgz/ooXgIyp1rf8ik5bGX8mpE2YHjC0P/eyQvxu1GURYQgq9ozf2mteQ5ZD9YiyQ==", + "dev": true + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "dev": true + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "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": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "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 + }, + "are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arity-n": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz", + "integrity": "sha512-fExL2kFDC1Q2DUOx3whE/9KoN66IzkY4b4zUHUBFM1ojEYjZZYDcUW3bek/ufGionX9giIKDC5redH2IlGqcQQ==", + "dev": true + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "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": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "dev": true + }, + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + }, + "array-includes": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", + "dev": true + }, + "array.prototype.flat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.reduce": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz", + "integrity": "sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + } + }, + "asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "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", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true + }, + "assets-webpack-plugin": { + "version": "3.9.12", + "resolved": "https://registry.npmjs.org/assets-webpack-plugin/-/assets-webpack-plugin-3.9.12.tgz", + "integrity": "sha512-iqXT/CtP013CO+IZJG7f4/KmUnde+nn6FSksAhrGRbT1GODsFU3xocP6A5NkTFoey3XOI9n1ZY0QmX/mY74gNA==", + "dev": true, + "requires": { + "camelcase": "5.3.1", + "escape-string-regexp": "2.0.0", + "lodash": "4.17.15", + "mkdirp": "0.5.3" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "mkdirp": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", + "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + } + } + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "dev": true + }, + "async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha512-VUeSMD8nEGBWaZK4lizI1sf3yEC7pnAQ/mrI7pC2fBz2s/tq5jWWEngTwaf0Gruu/OoXRGLGg1XFqpYBiGTYJA==", + "dev": true + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true + } + } + }, + "babel-core": { + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true + } + } + }, + "babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "dev": true, + "requires": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + }, + "dependencies": { + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true + } + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q==", + "dev": true, + "requires": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ==", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA==", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q==", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg==", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg==", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw==", + "dev": true, + "requires": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-loader": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.5.tgz", + "integrity": "sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ==", + "dev": true, + "requires": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^2.0.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA==", + "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", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-external-helpers": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-external-helpers/-/babel-plugin-external-helpers-6.22.0.tgz", + "integrity": "sha512-TdAMiM6MzLokhk3yCA0KCctmivVZ/mmCwbp7YPmRGkqh2KkcNuxE3R0jxuYU+4xmvfMZx4p4uo8d1cT9t5BLxA==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-module-resolver": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-3.2.0.tgz", + "integrity": "sha512-tjR0GvSndzPew/Iayf4uICWZqjBwnlMWjSx6brryfQ81F9rxBVqwDJtFCV8oOs0+vJeefK9TmdZtkIFdFe1UnA==", + "dev": true, + "requires": { + "find-babel-config": "^1.1.0", + "glob": "^7.1.2", + "pkg-up": "^2.0.0", + "reselect": "^3.0.1", + "resolve": "^1.4.0" + } + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.3", + "semver": "^6.1.1" + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", + "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.3.3", + "core-js-compat": "^3.25.1" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.3.3" + } + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw==", + "dev": true + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ==", + "dev": true + }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha512-C4Aq+GaAj83pRQ0EFgTvw5YO6T3Qz2KGrNRwIj9mSoNHVvdZY4KO2uA6HNtNXCw993iSZnckY1aLW8nOi8i4+w==", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ==", + "dev": true + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw==", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw==", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag==", + "dev": true, + "requires": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg==", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA==", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "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-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg==", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw==", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA==", + "dev": true, + "requires": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ==", + "dev": true, + "requires": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ==", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ==", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ==", + "dev": true, + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha512-ocgA9VJvyxwt+qJB0ncxV8kb/CjfTcECUY4tQ5VT7nP6Aohzobm8CDFaQ5FHdvZQzLmf0sgDxB8iRXZXxwZcyA==", + "dev": true, + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg==", + "dev": true, + "requires": { + "regenerator-transform": "^0.10.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": "sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw==", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-polyfill": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha512-F2rZGQnAdaHWQ8YAoeRbukc7HS9QgdgeyJ0rQDd485v9opwuPvjpPFcOOT/WmkKTdgy9ESgSPXDcTNpzrGr6iQ==", + "requires": { + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" + } + }, + "babel-preset-env": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", + "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^3.2.6", + "invariant": "^2.2.2", + "semver": "^5.3.0" + }, + "dependencies": { + "browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A==", + "dev": true, + "requires": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + } + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==", + "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": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==", + "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": { + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + } + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + } + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "optional": true + }, + "bindings": { + "version": "1.5.0", + "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" + } + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha512-OorbnJVPII4DuUKbjARAe8u8EfqOmkEEaSFIyoQ7OjTHn6kafxWl0wLgoZ2rXaYd7MyLcDaU4TmhfxtwgcccMQ==", + "dev": true, + "requires": { + "inherits": "~2.0.0" + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + }, + "body-parser": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true + }, + "qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + } + } + }, + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha512-RaVTblr+OnEli0r/ud8InrU7D+G0y6aJhlxaLa6Pwty4+xoxboF1BsUI45tujvRpbj9dQVoglChqonGAsjEBYg==", + "dev": true, + "requires": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "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": "^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" + } + } + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "dev": true + }, + "cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", + "dev": true, + "requires": { + "callsites": "^2.0.0" + }, + "dependencies": { + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", + "dev": true + } + } + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==", + "dev": true, + "requires": { + "callsites": "^0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==", + "dev": true + }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ==", + "dev": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", + "dev": true + } + } + }, + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001414", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001414.tgz", + "integrity": "sha512-t55jfSaWjCdocnFdKQoO+d2ct9C59UZg4dY3OnUlSZ447r8pUtIKdp0hpAzrGFultmTC+Us+KpKi4GZl/LXlFg==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg==", + "dev": true + }, + "chart.js": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz", + "integrity": "sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==", + "requires": { + "chartjs-color": "^2.1.0", + "moment": "^2.10.2" + } + }, + "chartjs-color": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz", + "integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==", + "requires": { + "chartjs-color-string": "^0.6.0", + "color-convert": "^1.9.3" + } + }, + "chartjs-color-string": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz", + "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==", + "requires": { + "color-name": "^1.0.0" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "optional": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "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" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "optional": 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, + "optional": 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, + "optional": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + } + }, + "clean-webpack-plugin": { + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-0.1.19.tgz", + "integrity": "sha512-M1Li5yLHECcN2MahoreuODul5LkjohJGFxLPTjl3j1ttKrF5rgjZET1SJduuqxLAuT1gAPOdkhg03qcaaU1KeA==", + "dev": true, + "requires": { + "rimraf": "^2.6.1" + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "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" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true + }, + "coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dev": true, + "requires": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dev": true, + "requires": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + }, + "dependencies": { + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + } + } + }, + "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==" + }, + "color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dev": true, + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "compose-function": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", + "integrity": "sha512-xzhzTJ5eC+gmIzvZq+C3kCJHsp9os6tJkrigDRZclyGtOKINbZtE8n1Tzmeh32jW+BUDPbvZpibwvJHBLGMVwg==", + "dev": true, + "requires": { + "arity-n": "^1.0.4" + } + }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "dev": true + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", + "dev": true + }, + "core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" + }, + "core-js-compat": { + "version": "3.25.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.3.tgz", + "integrity": "sha512-xVtYpJQ5grszDHEUU9O7XbjjcZ0ccX3LgQsyqSvTnjX97ZqEgn9F5srmrwwwMtbKzDllyFPL+O+2OFMl1lU4TQ==", + "dev": true, + "requires": { + "browserslist": "^4.21.4" + } + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "dependencies": { + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + } + } + }, + "create-ecdh": { + "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.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "integrity": "sha512-eZ+m1WNhSZutOa/uRblAc9Ut5MQfukFrFMtPSm3bZCA888NmMd5AWXWdgRZ80zd+pTk1P2JrGjg9pUPTvl2PWQ==", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha512-zj5D7X1U2h2zsXOAM8EyUREBnnts6H+Jm+d1M2DbiQQcUtnqgQsMrdo8JW9R80YFUmIdBZeMu5wvYM7hcgWP/Q==", + "dev": true + }, + "css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "dev": true, + "requires": { + "postcss": "^7.0.1", + "timsort": "^0.3.0" + } + }, + "css-loader": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-2.1.1.tgz", + "integrity": "sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w==", + "dev": true, + "requires": { + "camelcase": "^5.2.0", + "icss-utils": "^4.1.0", + "loader-utils": "^1.2.3", + "normalize-path": "^3.0.0", + "postcss": "^7.0.14", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^2.0.6", + "postcss-modules-scope": "^2.1.0", + "postcss-modules-values": "^2.0.0", + "postcss-value-parser": "^3.3.0", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + } + } + }, + "css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + } + }, + "css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "dev": true + }, + "css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dev": true, + "requires": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + } + }, + "css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "cssnano": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", + "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", + "dev": true, + "requires": { + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.8", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "cssnano-preset-default": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", + "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", + "dev": true, + "requires": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.3", + "postcss-unique-selectors": "^4.0.1" + } + }, + "cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha512-6RIcwmV3/cBMG8Aj5gucQRsJb4vv4I4rn6YjPbVWd5+Pn/fuG+YseGvXGk00XLkoZkaj31QOD7vMUpNPC4FIuw==", + "dev": true + }, + "cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha512-JPMZ1TSMRUPVIqEalIBNoBtAYbi8okvcFns4O0YIhcdGebeYZK7dMyHJiQ6GqNBA9kE0Hym4Aqym5rPdsV/4Cw==", + "dev": true + }, + "cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", + "dev": true + }, + "csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "requires": { + "css-tree": "^1.1.2" + }, + "dependencies": { + "css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "requires": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + } + }, + "mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + } + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==", + "dev": true + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "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" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==", + "dev": true + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dev": true, + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "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" + } + }, + "define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dev": true, + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "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": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "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": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "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 + } + } + }, + "del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", + "dev": true + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A==", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==", + "dev": true + }, + "dns-packet": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", + "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", + "dev": true, + "requires": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha512-Ix5PrWjphuSoUXV/Zv5gaFHjnaJtb02F2+Si3Ht9dyJ87+Z/lMmy+dpNHtTGraNK958ndXq2i+GLkWsWHcKaBQ==", + "dev": true, + "requires": { + "buffer-indexof": "^1.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dev": true, + "requires": { + "utila": "~0.4" + } + }, + "dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true + }, + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.4.268", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.268.tgz", + "integrity": "sha512-PO90Bv++vEzdln+eA9qLg1IRnh0rKETus6QkTzcFm5P3Wg3EQBZud5dcnzkpYXuIKWBjKe5CO8zjz02cicvn1g==", + "dev": true + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "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 + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", + "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "dependencies": { + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + } + } + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true + }, + "errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "dev": true, + "requires": { + "stackframe": "^1.3.4" + } + }, + "es-abstract": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.3.tgz", + "integrity": "sha512-AyrnaKVpMzljIdwjzrj+LxGmj8ik2LckwXacHqrJJ/jxz6dDDBcZ7I7nlHM0FvEW8MfbWJwOd+yT2XzYW49Frw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.6", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.2", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + } + }, + "es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "dev": true, + "requires": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "eslint": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", + "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", + "dev": true, + "requires": { + "ajv": "^5.3.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.4", + "esquery": "^1.0.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.0.1", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^1.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", + "table": "4.0.2", + "text-table": "~0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "eslint-config-airbnb-base": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz", + "integrity": "sha512-/vjm0Px5ZCpmJqnjIzcFb9TKZrKWz0gnuG/7Gfkt0Db1ELJR51xkZth+t14rYdqWgX836XbuxtArbIHlVhbLBA==", + "dev": true, + "requires": { + "eslint-restricted-globals": "^0.1.1" + } + }, + "eslint-import-resolver-babel-module": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-babel-module/-/eslint-import-resolver-babel-module-4.0.0.tgz", + "integrity": "sha512-aPj0+pG0H3HCaMD9eRDYEzPdMyKrLE2oNhAzTXd2w86ZBe3s7drSrrPwVTfzO1CBp13FGk8S84oRmZHZvSo0mA==", + "dev": true, + "requires": { + "pkg-up": "^2.0.0", + "resolve": "^1.4.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-module-utils": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "dev": true, + "requires": { + "debug": "^3.2.7" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "dev": true, + "requires": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + } + }, + "eslint-restricted-globals": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", + "integrity": "sha512-d1cerYC0nOJbObxUe1kR8MZ25RLt7IHzR9d+IOupoMqFU03tYjo7Stjqj04uHx1xx7HKSE9/NjdeBiP4/jUP8Q==", + "dev": true + }, + "eslint-scope": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "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": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "requires": { + "acorn": "^5.5.0", + "acorn-jsx": "^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 + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "eventsource": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", + "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "express": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", + "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "dev": true, + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.0", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.10.3", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + } + } + }, + "ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "requires": { + "type": "^2.7.2" + }, + "dependencies": { + "type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "dev": true, + "requires": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true + }, + "fast-async": { + "version": "6.3.8", + "resolved": "https://registry.npmjs.org/fast-async/-/fast-async-6.3.8.tgz", + "integrity": "sha512-TjlooyqrYm/gOXjD2UHNwfrWkvTbzU105Nk4bvcRTeRoL+wIeK6rqbqDg3CN9z5p37cE2iXhP6SxQFz8OVIaUg==", + "dev": true, + "requires": { + "nodent-compiler": "^3.2.10", + "nodent-runtime": ">=3.2.1" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==", + "dev": true, + "requires": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + } + }, + "file-loader": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", + "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==", + "dev": true, + "requires": { + "loader-utils": "^1.0.2", + "schema-utils": "^0.4.5" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "schema-utils": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", + "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + } + }, + "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" + } + }, + "find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "dev": true, + "requires": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true + }, + "friendly-errors-webpack-plugin": { + "version": "2.0.0-beta.2", + "resolved": "https://registry.npmjs.org/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-2.0.0-beta.2.tgz", + "integrity": "sha512-0x14cdjGx5q0yZc3Cy9sgAF/szWUFx1WxH/IX88UuKbM5Z+7FCk/Z/6hFbXMcz3qqK0mp7WrHKX3cxhUAL2aqQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "error-stack-parser": "^2.0.2", + "string-width": "^2.0.0", + "strip-ansi": "^5" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "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" + } + } + } + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.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" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, + "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": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "dev": true, + "requires": { + "globule": "^1.0.0" + } + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==", + "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" + }, + "dependencies": { + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "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": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "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": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "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": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "globule": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz", + "integrity": "sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg==", + "dev": true, + "requires": { + "glob": "~7.1.1", + "lodash": "^4.17.21", + "minimatch": "~3.0.2" + }, + "dependencies": { + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "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" + } + }, + "minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "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==", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + } + } + }, + "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": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", + "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": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", + "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": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "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" + } + }, + "hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "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": "sha512-M5ezZw4LzXbBKMruP+BNANf0k+19hDQMgpzBIYnya//Al+fjNct9Wf3b1WedLqdEs2hKBvxq/jh+DsHJLj0F9A==", + "dev": true + }, + "hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha512-7Wn5GMLuHBjZCb2bTmnDOycho0p/7UVaAeqXZGbHrBCl6Yd/xDhQJAXe6Ga9AXJH2I5zY1dEdYw2u1UptnSBJA==", + "dev": true + }, + "html-entities": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", + "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==", + "dev": true + }, + "htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "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": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "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": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==", + "dev": true + }, + "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.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==", + "dev": true + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "dependencies": { + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "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==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.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-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" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "in-publish": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz", + "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg==", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==", + "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": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "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.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.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" + } + }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "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": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", + "dev": true + }, + "ip": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", + "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==", + "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": "sha512-vOx7VprsKyllwjSkLV79NIhpyLfr3jAp7VaTCMXOJHu4m0Ew1CZ2fcjASwmV1jI3BWuWHB013M48eyeldk9gYg==", + "dev": true + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.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-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^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.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true + }, + "is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha512-H1U8Vz0cfXNujrJzEcvvwMDW9Ra+biSYA3ThdQvAnMLJkEHQXn6bWzLkxHtVYJ+Sdbx0b6finn3jZiaVe7MAHA==", + "dev": true, + "requires": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + } + }, + "is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "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": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "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": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "is-path-inside": "^2.1.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==", + "dev": true, + "requires": { + "path-is-inside": "^1.0.2" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", + "dev": true + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, + "jquery": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz", + "integrity": "sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw==" + }, + "jquery.dirtyforms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jquery.dirtyforms/-/jquery.dirtyforms-2.0.0.tgz", + "integrity": "sha512-iGhN+ESRCYgR1Tz3Z5RwKhCZi+1LMQiglHxghtTk10O1KmjvZwd2HUrSsV9Zn3ntFgDzYcQcLNERUAAF4RDT/A==", + "requires": { + "jquery": ">=1.4.2" + } + }, + "js-base64": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "last-call-webpack-plugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", + "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", + "dev": true, + "requires": { + "lodash": "^4.17.5", + "webpack-sources": "^1.1.0" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lightbox2": { + "version": "2.11.3", + "resolved": "https://registry.npmjs.org/lightbox2/-/lightbox2-2.11.3.tgz", + "integrity": "sha512-Q4v6il/OK9ttgEkAxSok/jrI/LUbqTrePFchqP2x/59qaDIZgJjEEc5Xf7peSMc/55Zo5PAgmX6EiN/BeEeUBQ==" + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + } + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", + "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "dependencies": { + "json5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true + } + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "loglevel": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz", + "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "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": { + "semver": "^6.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA==", + "dev": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha512-e6RM36aegd4f+r8BZCcYXlO2P3H6xbUM6ktL2Xmf45GAOit9bI4z6/3VU7JwllVO1L7u0UDSg/EhzQ5lmMLolA==", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "dependencies": { + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "mini-css-extract-plugin": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.2.tgz", + "integrity": "sha512-ots7URQH4wccfJq9Ssrzu2+qupbncAce4TmTzunI9CIwlQMp2XI+WNUw6xWF6MMAGAm1cbUVINrSjATaVMyKXg==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + } + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, + "moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dev": true, + "requires": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + } + }, + "multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha512-cnAsSVxIDsYt0v7HmC0hWZFwwXSh+E6PgCrREDuN/EsjgLwA5XRmlMHhSiDPrt6HxY1gTivEa/Zh7GtODoLevQ==", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", + "dev": true + }, + "nan": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", + "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", + "dev": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true + }, + "neo-async": { + "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 + }, + "next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "dev": true + }, + "node-gyp": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", + "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", + "dev": true, + "requires": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha512-mfmm3/H9+67MCVix1h+IXTpDwL6710LyHuk7+cWC9T1mE0qz4iHhh6r4hU2wrIT9iTsAAC2XQRvfblL028cpLw==", + "dev": true + } + } + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + } + } + }, + "node-releases": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "dev": true + }, + "node-sass": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz", + "integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==", + "dev": true, + "requires": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^3.0.0", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "in-publish": "^2.0.0", + "lodash": "^4.17.15", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.13.2", + "node-gyp": "^3.8.0", + "npmlog": "^4.0.0", + "request": "^2.88.0", + "sass-graph": "2.2.5", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true + } + } + }, + "nodent-compiler": { + "version": "3.2.13", + "resolved": "https://registry.npmjs.org/nodent-compiler/-/nodent-compiler-3.2.13.tgz", + "integrity": "sha512-nzzWPXZwSdsWie34om+4dLrT/5l1nT/+ig1v06xuSgMtieJVAnMQFuZihUwREM+M7dFso9YoHfDmweexEXXrrw==", + "dev": true, + "requires": { + "acorn": ">= 2.5.2 <= 5.7.5", + "acorn-es7-plugin": "^1.1.7", + "nodent-transform": "^3.2.9", + "source-map": "^0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true + } + } + }, + "nodent-runtime": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/nodent-runtime/-/nodent-runtime-3.2.1.tgz", + "integrity": "sha512-7Ws63oC+215smeKJQCxzrK21VFVlCFBkwl0MOObt0HOpVQXs3u483sAmtkF33nNqZ5rSOQjB76fgyPBmAUrtCA==", + "dev": true + }, + "nodent-transform": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/nodent-transform/-/nodent-transform-3.2.9.tgz", + "integrity": "sha512-4a5FH4WLi+daH/CGD5o/JWRR8W5tlCkd3nrDSkxbOzscJTyTUITltvOJeQjg3HJ1YgEuNyiPhQbvbtRjkQBByQ==", + "dev": true + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "requires": { + "boolbase": "^1.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "dev": true + }, + "object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "object.entries": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz", + "integrity": "sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==", + "dev": true, + "requires": { + "array.prototype.reduce": "^1.0.4", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, + "optimize-css-assets-webpack-plugin": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.8.tgz", + "integrity": "sha512-mgFS1JdOtEGzD8l+EuISqL57cKO+We9GcoiQEmdCWRqqck+FGNmYJtx9qfAPzEz+lRrlThWMuGDaRkI/yWNx/Q==", + "dev": true, + "requires": { + "cssnano": "^4.1.10", + "last-call-webpack-plugin": "^3.0.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", + "dev": true + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", + "dev": true, + "requires": { + "lcid": "^1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "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-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "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-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + }, + "dependencies": { + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "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 + }, + "p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "dev": true, + "requires": { + "retry": "^0.12.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 + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "parse-asn1": { + "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": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "optional": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } + } + }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha512-fjAPuiws93rm7mPUu21RdBnkeZNrbfCFCwfAhPWY+rR3zG0ubpe5cEReHOw5fIbfmsxEV/g2kSxGTATY3Bpnwg==", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "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 + }, + "portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", + "dev": true, + "requires": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", + "dev": true + }, + "postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "requires": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "dependencies": { + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + } + } + }, + "postcss-calc": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", + "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", + "dev": true, + "requires": { + "postcss": "^7.0.27", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.2" + }, + "dependencies": { + "postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + } + } + }, + "postcss-colormin": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", + "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-discard-comments": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", + "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-merge-longhand": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", + "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "dev": true, + "requires": { + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" + } + }, + "postcss-merge-rules": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", + "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-minify-font-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-minify-gradients": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", + "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-minify-params": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", + "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" + } + }, + "postcss-minify-selectors": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", + "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "dev": true, + "requires": { + "postcss": "^7.0.5" + } + }, + "postcss-modules-local-by-default": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz", + "integrity": "sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA==", + "dev": true, + "requires": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0", + "postcss-value-parser": "^3.3.1" + } + }, + "postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "dev": true, + "requires": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" + } + }, + "postcss-modules-values": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz", + "integrity": "sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w==", + "dev": true, + "requires": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^7.0.6" + } + }, + "postcss-normalize-charset": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-normalize-display-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", + "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-positions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", + "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-repeat-style": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", + "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-string": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", + "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "dev": true, + "requires": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-timing-functions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", + "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-unicode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "dev": true, + "requires": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-whitespace": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", + "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-ordered-values": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", + "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-reduce-initial": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", + "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "postcss-reduce-transforms": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", + "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-svgo": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", + "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + } + }, + "postcss-unique-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true + }, + "pretty-error": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", + "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", + "dev": true, + "requires": { + "lodash": "^4.17.20", + "renderkid": "^2.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 + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "dev": true + }, + "psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "dev": true + }, + "qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", + "dev": true + }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + } + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "optional": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g==", + "dev": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.2" + } + }, + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha512-02YopEIhAgiBHWeoTiA8aitHDt8z6w+rQqNuIftlM+ZtvSl/brTouaU7DW6GO/cHtvxJvS4Hwv2ibKdxIRi24w==" + }, + "regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "regex-parser": { + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", + "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==", + "dev": true + }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, + "regexpp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", + "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", + "dev": true + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ==", + "dev": true, + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g==", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true + }, + "renderkid": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.7.tgz", + "integrity": "sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==", + "dev": true, + "requires": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^3.0.1" + } + }, + "repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", + "dev": true + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==", + "dev": true, + "requires": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "reselect": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-3.0.1.tgz", + "integrity": "sha512-b/6tFZCmRhtBMa4xGqiiRp9jh9Aqi2A687Lo265cN0/QohJQEBPiQ52f4QB6i0eF3yp3hmLL21LSGBcML2dlxA==", + "dev": true + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg==", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true + } + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", + "dev": true + }, + "resolve-url-loader": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.4.tgz", + "integrity": "sha512-D3sQ04o0eeQEySLrcz4DsX3saHfsr8/N6tfhblxgZKXxMT2Louargg12oGNfoTRLV09GXhVUe5/qgA5vdgNigg==", + "dev": true, + "requires": { + "adjust-sourcemap-loader": "3.0.0", + "camelcase": "5.3.1", + "compose-function": "3.0.3", + "convert-source-map": "1.7.0", + "es6-iterator": "2.0.3", + "loader-utils": "1.2.3", + "postcss": "7.0.36", + "rework": "1.0.1", + "rework-visit": "1.0.0", + "source-map": "0.6.1" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true + }, + "rework": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz", + "integrity": "sha512-eEjL8FdkdsxApd0yWVZgBGzfCQiT8yqSc2H1p4jpZpQdtz7ohETiDMoje5PlM8I9WgkqkreVxFUKYOiJdVWDXw==", + "dev": true, + "requires": { + "convert-source-map": "^0.3.3", + "css": "^2.0.0" + }, + "dependencies": { + "convert-source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", + "integrity": "sha512-+4nRk0k3oEpwUB7/CalD7xE2z4VmtEnnq0GO2IPTkrooTrAhEsWvuLF5iWP1dXrwluki/azwXV1ve7gtYuPldg==", + "dev": true + } + } + }, + "rework-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz", + "integrity": "sha512-W6V2fix7nCLUYX1v6eGPrBOZlc03/faqzP4sUxMAJMBMOPYhfV/RyLegTufn5gJKaOITyi+gvf0LXDZ9NzkHnQ==", + "dev": true + }, + "rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha512-gDK5mkALDFER2YLqH6imYvK6g02gpNGM4ILDZ472EwWfXZnC2ZEpoB2ECXTyOVUKuk/bPJZMzwQPBYICzP+D3w==", + "dev": true + }, + "rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha512-zgn5OjNQXLUTdq8m17KdaicF6w89TZs8ZU8y0AYENIU6wG8GG6LLm0yLSiPY8DmaYmHdgRW8rnApjoT0fQRfMg==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha512-Cun9QucwK6MIrp3mry/Y7hqD1oFqTYLQ4pGxaHTjIdaFDWRGGLikqp6u8LcWJnzpoALg9hap+JGk8sFIUuEGNA==", + "dev": true + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha512-3xPNZGW93oCjiO7PtKxRK6iOVYBWBvtf9QHDfU23Oc+dLIQmAV//UnyXV/yihv81VS/UqoQPk4NegS8EFi55Hg==", + "dev": true, + "requires": { + "rx-lite": "*" + } + }, + "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 + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sass-graph": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz", + "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==", + "dev": true, + "requires": { + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^13.3.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "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" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "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 + }, + "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-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" + } + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "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" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "dev": true + }, + "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" + } + } + } + }, + "sass-loader": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.3.1.tgz", + "integrity": "sha512-tuU7+zm0pTCynKYHpdqaPpe+MMTQ76I9TPZ7i4/5dZsigE350shQWe5EZNl5dBidM49TPET75tNqRbcsUZWeNA==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "loader-utils": "^1.0.1", + "neo-async": "^2.5.0", + "pify": "^4.0.1", + "semver": "^6.3.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "schema-utils": { + "version": "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" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + } + } + }, + "scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha512-dYE8LhncfBUar6POCxMTm0Ln+erjeczqEvCJib5/7XNkdw1FkUGgwMPY360FY0FgPWQxHWCx29Jl3oejyGLM9Q==", + "dev": true, + "requires": { + "js-base64": "^2.1.8", + "source-map": "^0.4.2" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha512-Y8nIfcb1s/7DcobUz1yOO1GSp7gyL+D9zLHDehT7iRESqGSxjJ448Sg7rvfgsRJCnKLdSl11uGf0s9X80cH0/A==", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true + }, + "selfsigned": { + "version": "1.10.14", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.14.tgz", + "integrity": "sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA==", + "dev": true, + "requires": { + "node-forge": "^0.10.0" + } + }, + "semantic-ui-css": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/semantic-ui-css/-/semantic-ui-css-2.4.1.tgz", + "integrity": "sha512-Pkp0p9oWOxlH0kODx7qFpIRYpK1T4WJOO4lNnpNPOoWKCrYsfHqYSKgk5fHfQtnWnsAKy7nLJMW02bgDWWFZFg==", + "requires": { + "jquery": "x.*" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + } + }, + "serialize-javascript": { + "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", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true + } + } + }, + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "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", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dev": true, + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true + } + } + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", + "dev": true + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0" + } + }, + "slick-carousel": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz", + "integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA==", + "requires": {} + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "requires": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + }, + "dependencies": { + "faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + } + } + }, + "sockjs-client": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.6.1.tgz", + "integrity": "sha512-2g0tjOR+fRs0amxENLi/q5TiJTqY+WXFOzb5UwXndlK6TO3U/mirZznpx6w34HVMoc3g7cY24yC/ZMIYnDlfkw==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "eventsource": "^2.0.2", + "faye-websocket": "^0.11.4", + "inherits": "^2.0.4", + "url-parse": "^1.5.10" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "dev": true + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", + "dev": true + }, + "spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "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" + } + } + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + }, + "dependencies": { + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "ssri": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", + "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, + "stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + } + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + }, + "stdout-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", + "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "string.prototype.trimend": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "dev": true + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA==", + "dev": true, + "requires": { + "get-stdin": "^4.0.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true + }, + "style-loader": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.21.0.tgz", + "integrity": "sha512-T+UNsAcl3Yg+BsPKs1vd22Fr8sVT+CJMtzqc6LEw9bbJZb43lm9GoeIfUcDEefBSWC0BhYbcdupV1GtI4DGzxg==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "schema-utils": "^0.4.5" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "schema-utils": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", + "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "stylehacks": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", + "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "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" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "dependencies": { + "css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "dev": true + }, + "dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + }, + "dependencies": { + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + } + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + } + } + }, + "table": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, + "requires": { + "ajv": "^5.2.3", + "ajv-keywords": "^2.1.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + }, + "dependencies": { + "ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha512-ZFztHzVRdGLAzJmpUT9LNFLe1YiVOEylcaNpEutM26PVTCtOD919IMfD01CgbRouB42Dd9atjx1HseC15DgOZA==", + "dev": true, + "requires": {} + } + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "tar": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", + "dev": true, + "requires": { + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" + } + }, + "terser": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", + "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + } + } + }, + "terser-webpack-plugin": { + "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": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "dependencies": { + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "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" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.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" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==", + "dev": true + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", + "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": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "dependencies": { + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw==", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==", + "dev": true + }, + "true-case-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", + "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", + "dev": true, + "requires": { + "glob": "^7.1.2" + } + }, + "tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", + "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==", + "dev": true + }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha512-mZdDpf3vBV5Efh29kMw5tXoup/buMgxLzOt/XKFKcVmi+15ManNQWr6HfZ2aiZTYlYixbdNJ0KFmIZIv52tHSQ==", + "dev": true + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true + }, + "unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "update-browserslist-db": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz", + "integrity": "sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "dev": true + } + } + }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + } + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true + }, + "vendors": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", + "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + } + } + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "watchpack": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", + "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", + "dev": true, + "requires": { + "chokidar": "^3.4.1", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.1" + } + }, + "watchpack-chokidar2": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", + "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", + "dev": true, + "optional": true, + "requires": { + "chokidar": "^2.1.8" + }, + "dependencies": { + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "optional": true + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "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" + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + } + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "webpack": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", + "integrity": "sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.5.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.7.4", + "webpack-sources": "^1.4.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + } + } + }, + "webpack-cli": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz", + "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "enhanced-resolve": "^4.1.1", + "findup-sync": "^3.0.0", + "global-modules": "^2.0.0", + "import-local": "^2.0.0", + "interpret": "^1.4.0", + "loader-utils": "^1.4.0", + "supports-color": "^6.1.0", + "v8-compile-cache": "^2.1.1", + "yargs": "^13.3.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "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" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "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" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "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" + } + }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "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 + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + } + }, + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "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-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" + } + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "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" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "dev": true + }, + "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" + } + } + } + }, + "webpack-dev-middleware": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz", + "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==", + "dev": true, + "requires": { + "memory-fs": "^0.4.1", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + }, + "dependencies": { + "mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true + } + } + }, + "webpack-dev-server": { + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.3.tgz", + "integrity": "sha512-3x31rjbEQWKMNzacUZRE6wXvUFuGpH7vr0lIEbYpMAG9BOxi0928QU1BBswOAP3kg3H1O4hiS+sq4YyAn6ANnA==", + "dev": true, + "requires": { + "ansi-html-community": "0.0.8", + "bonjour": "^3.5.0", + "chokidar": "^2.1.8", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.3.1", + "http-proxy-middleware": "0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", + "killable": "^1.0.1", + "loglevel": "^1.6.8", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.26", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.8", + "semver": "^6.3.0", + "serve-index": "^1.9.1", + "sockjs": "^0.3.21", + "sockjs-client": "^1.5.0", + "spdy": "^4.0.2", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.2", + "webpack-log": "^2.0.0", + "ws": "^6.2.1", + "yargs": "^13.3.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "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" + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "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" + } + }, + "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" + } + }, + "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 + }, + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "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": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", + "dev": true, + "requires": { + "binary-extensions": "^1.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" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "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" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "dev": true + }, + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "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" + } + } + } + }, + "webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "requires": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "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 + } + } + }, + "webpack-manifest-plugin": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-2.2.0.tgz", + "integrity": "sha512-9S6YyKKKh/Oz/eryM1RyLVDVmy3NSPV0JXMRhZ18fJsq+AwGxUY34X54VNwkzYcEmEkDwNxuEOboCZEebJXBAQ==", + "dev": true, + "requires": { + "fs-extra": "^7.0.0", + "lodash": ">=3.5 <5", + "object.entries": "^1.1.0", + "tapable": "^1.0.0" + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "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 + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", + "dev": true + }, + "wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha512-CJ17OoULEKXpA5pef3qLj5AxTJ6mSt7g84he2WIskKwqFO4T97d5V7Tadl0DYDk7qyUOQD5WlUlOMChaYrhxeA==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true + }, + "yargs": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", + "integrity": "sha512-6/QWTdisjnu5UHUzQGst+UOEuEVwIzFVGBjq3jMTFNs5WJQsH/X6nMURSaScIdF5txylr1Ao9bvbWiKi2yXbwA==", + "dev": true, + "requires": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^4.2.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "y18n": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", + "dev": true + }, + "yargs-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "integrity": "sha512-+QQWqC2xeL0N5/TE+TY6OGEqyNRM+g2/r712PDNYgiCdXYCApXf1vzfmDSLBxfGRwV+moTq/V8FnMI24JCm2Yg==", + "dev": true, + "requires": { + "camelcase": "^3.0.0" + } + } + } + }, + "yargs-parser": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-12.0.0.tgz", + "integrity": "sha512-WQM8GrbF5TKiACr7iE3I2ZBNC7qC9taKPMfjJaMD2LkOJQhIctASxKXdFAOPim/m47kgAQBVIaPlFjnRdkol7w==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } + } + } + } +} diff --git a/OpenMarketplace/package.json b/OpenMarketplace/package.json new file mode 100644 index 0000000..ae103bb --- /dev/null +++ b/OpenMarketplace/package.json @@ -0,0 +1,43 @@ +{ + "dependencies": { + "babel-polyfill": "^6.26.0", + "chart.js": "^2.9.3", + "jquery": "^3.5.0", + "jquery.dirtyforms": "^2.0.0", + "lightbox2": "^2.9.0", + "semantic-ui-css": "^2.2.0", + "slick-carousel": "^1.8.1" + }, + "devDependencies": { + "@symfony/webpack-encore": "^1.7.0", + "babel-core": "^6.26.3", + "babel-plugin-external-helpers": "^6.22.0", + "babel-plugin-module-resolver": "^3.1.1", + "babel-plugin-transform-object-rest-spread": "^6.26.0", + "babel-preset-env": "^1.7.0", + "babel-register": "^6.26.0", + "dedent": "^0.7.0", + "eslint": "^4.19.1", + "eslint-config-airbnb-base": "^12.1.0", + "eslint-import-resolver-babel-module": "^4.0.0", + "eslint-plugin-import": "^2.11.0", + "fast-async": "^6.3.7", + "file-loader": "^6.0.0", + "merge-stream": "^1.0.0", + "node-sass": "^4.14", + "sass-loader": "^7.0.1", + "upath": "^1.1.0", + "yargs": "^6.4.0" + }, + "scripts": { + "dev": "encore dev", + "watch": "encore dev --watch", + "prod": "encore production" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Sylius/Sylius.git" + }, + "author": "Paweł Jędrzejewski", + "license": "MIT" +} diff --git a/OpenMarketplace/phpspec.yml.dist b/OpenMarketplace/phpspec.yml.dist new file mode 100644 index 0000000..2029150 --- /dev/null +++ b/OpenMarketplace/phpspec.yml.dist @@ -0,0 +1,6 @@ +suites: + app: + namespace: BitBag\OpenMarketplace + psr4_prefix: BitBag\OpenMarketplace + src_path: src/ + diff --git a/OpenMarketplace/phpstan.neon b/OpenMarketplace/phpstan.neon new file mode 100644 index 0000000..4b0940b --- /dev/null +++ b/OpenMarketplace/phpstan.neon @@ -0,0 +1,17 @@ +parameters: + level: 8 + reportUnmatchedIgnoredErrors: false + checkMissingIterableValueType: false + checkGenericClassInNonGenericObjectType: false + + excludePaths: + # Makes PHPStan crash + - 'src/DependencyInjection/Configuration.php' + + # Test dependencies + - 'tests/Application/app/**.php' + - 'tests/Application/src/**.php' + + ignoreErrors: + - '/Parameter #1 \$configuration of method Symfony\\Component\\DependencyInjection\\Extension\\Extension::processConfiguration\(\) expects Symfony\\Component\\Config\\Definition\\ConfigurationInterface, Symfony\\Component\\Config\\Definition\\ConfigurationInterface\|null given\./' + - '/Cannot call method [a-z]+Node\(\) on Symfony\\Component\\Config\\Definition\\Builder\\NodeParentInterface\|null\./' diff --git a/OpenMarketplace/phpunit.xml.dist b/OpenMarketplace/phpunit.xml.dist new file mode 100644 index 0000000..6cbda91 --- /dev/null +++ b/OpenMarketplace/phpunit.xml.dist @@ -0,0 +1,25 @@ + + + + + + tests + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/public/.htaccess b/OpenMarketplace/public/.htaccess new file mode 100644 index 0000000..6d02fc2 --- /dev/null +++ b/OpenMarketplace/public/.htaccess @@ -0,0 +1,73 @@ +# Use the front controller as index file. It serves as a fallback solution when +# every other rewrite/redirect fails (e.g. in an aliased environment without +# mod_rewrite). Additionally, this reduces the matching process for the +# start page (path "/") because otherwise Apache will apply the rewriting rules +# to each configured DirectoryIndex file (e.g. index.php, index.html, index.pl). +DirectoryIndex index.php + +# By default, Apache does not evaluate symbolic links if you did not enable this +# feature in your server configuration. Uncomment the following line if you +# install assets as symlinks or if you experience problems related to symlinks +# when compiling LESS/Sass/CoffeScript assets. +# Options FollowSymlinks + +# Disabling MultiViews prevents unwanted negotiation, e.g. "/index" should not resolve +# to the front controller "/index.php" but be rewritten to "/index.php/index". + + Options -MultiViews + + + + RewriteEngine On + + # Determine the RewriteBase automatically and set it as environment variable. + # If you are using Apache aliases to do mass virtual hosting or installed the + # project in a subdirectory, the base path will be prepended to allow proper + # resolution of the index.php file and to redirect to the correct URI. It will + # work in environments without path prefix as well, providing a safe, one-size + # fits all solution. But as you do not need it in this case, you can comment + # the following 2 lines to eliminate the overhead. + RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$ + RewriteRule ^(.*) - [E=BASE:%1] + + # Sets the HTTP_AUTHORIZATION header removed by Apache + RewriteCond %{HTTP:Authorization} . + RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + # Redirect to URI without front controller to prevent duplicate content + # (with and without `/index.php`). Only do this redirect on the initial + # rewrite by Apache and not on subsequent cycles. Otherwise we would get an + # endless redirect loop (request -> rewrite to front controller -> + # redirect -> request -> ...). + # So in case you get a "too many redirects" error or you always get redirected + # to the start page because your Apache does not expose the REDIRECT_STATUS + # environment variable, you have 2 choices: + # - disable this feature by commenting the following 2 lines or + # - use Apache >= 2.3.9 and replace all L flags by END flags and remove the + # following RewriteCond (best solution) + RewriteCond %{ENV:REDIRECT_STATUS} ^$ + RewriteRule ^index\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L] + + # If the requested filename exists, simply serve it. + # We only want to let Apache serve files and not directories. + RewriteCond %{REQUEST_FILENAME} -f + RewriteRule ^ - [L] + + # Rewrite all other queries to the front controller. + RewriteRule ^ %{ENV:BASE}/index.php [L] + + + + + # When mod_rewrite is not available, we instruct a temporary redirect of + # the start page to the front controller explicitly so that the website + # and the generated links can still be used. + RedirectMatch 307 ^/$ /index.php/ + # RedirectTemp cannot be used instead + + + + + # Prevent clickjacking + Header set X-Frame-Options SAMEORIGIN + diff --git a/OpenMarketplace/public/favicon.svg b/OpenMarketplace/public/favicon.svg new file mode 100644 index 0000000..61aaa83 --- /dev/null +++ b/OpenMarketplace/public/favicon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/OpenMarketplace/public/index.php b/OpenMarketplace/public/index.php new file mode 100644 index 0000000..f094a9b --- /dev/null +++ b/OpenMarketplace/public/index.php @@ -0,0 +1,27 @@ +handle($request); +$response->send(); +$kernel->terminate($request, $response); diff --git a/OpenMarketplace/public/open-marketplace-logo.png b/OpenMarketplace/public/open-marketplace-logo.png new file mode 100644 index 0000000..ee00a5c Binary files /dev/null and b/OpenMarketplace/public/open-marketplace-logo.png differ diff --git a/OpenMarketplace/public/robots.txt b/OpenMarketplace/public/robots.txt new file mode 100644 index 0000000..214e411 --- /dev/null +++ b/OpenMarketplace/public/robots.txt @@ -0,0 +1,4 @@ +# www.robotstxt.org/ +# www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449 + +User-agent: * diff --git a/OpenMarketplace/spec/Component/Core/Api/Context/VendorContextSpec.php b/OpenMarketplace/spec/Component/Core/Api/Context/VendorContextSpec.php new file mode 100644 index 0000000..82ce7f7 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Context/VendorContextSpec.php @@ -0,0 +1,61 @@ +beConstructedWith($userContext); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(VendorContext::class); + } + + public function it_returns_vendor_for_current_vendor_context( + UserContextInterface $userContext, + ShopUserInterface $shopUser, + VendorInterface $vendor + ): void { + $shopUser->getVendor()->willReturn($vendor); + $userContext->getUser()->willReturn($shopUser); + + $this->getVendor()->shouldReturn($vendor); + } + + public function it_returns_null_when_there_is_not_vendor_context( + UserContextInterface $userContext, + ShopUserInterface $shopUser + ): void { + $shopUser->getVendor()->willReturn(null); + $userContext->getUser()->willReturn($shopUser); + + $this->getVendor()->shouldReturn(null); + } + + public function it_returns_null_when_there_is_not_shop_user_context( + UserContextInterface $userContext + ): void { + $userContext->getUser()->willReturn(null); + + $this->getVendor()->shouldReturn(null); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Controller/Vendor/DeleteProductListingActionSpec.php b/OpenMarketplace/spec/Component/Core/Api/Controller/Vendor/DeleteProductListingActionSpec.php new file mode 100644 index 0000000..ab1ccb8 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Controller/Vendor/DeleteProductListingActionSpec.php @@ -0,0 +1,60 @@ +beConstructedWith($entityManager); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(DeleteProductListingAction::class); + } + + public function it_deletes_product_listing_without_product( + ListingInterface $productListing, + EntityManagerInterface $entityManager + ): void { + $productListing->getProduct()->willReturn(null); + + $this($productListing)->shouldBeAnInstanceOf(JsonResponse::class); + + $productListing->remove()->shouldHaveBeenCalled(); + $entityManager->persist($productListing)->shouldHaveBeenCalled(); + $entityManager->flush()->shouldHaveBeenCalled(); + } + + public function it_deletes_product_listing_with_product( + ListingInterface $productListing, + EntityManagerInterface $entityManager, + ProductInterface $product + ): void { + $productListing->getProduct()->willReturn($product); + + $this($productListing)->shouldBeAnInstanceOf(JsonResponse::class); + + $productListing->remove()->shouldHaveBeenCalled(); + $product->setEnabled(false)->shouldHaveBeenCalled(); + $entityManager->persist($product)->shouldHaveBeenCalled(); + $entityManager->persist($productListing)->shouldHaveBeenCalled(); + $entityManager->flush()->shouldHaveBeenCalled(); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Controller/Vendor/SendToVerificationActionSpec.php b/OpenMarketplace/spec/Component/Core/Api/Controller/Vendor/SendToVerificationActionSpec.php new file mode 100644 index 0000000..a4d790c --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Controller/Vendor/SendToVerificationActionSpec.php @@ -0,0 +1,54 @@ +beConstructedWith($productDraftStateMachineTransition); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(SendToVerificationAction::class); + } + + public function it_does_nothing_when_cant_be_verified( + ProductDraftStateMachineTransitionInterface $productDraftStateMachineTransition, + ListingInterface $productListing, + ): void { + $productListing->canBeVerified()->willReturn(false); + + $this->__invoke($productListing)->shouldReturn($productListing); + } + + public function it_applies_when_can( + ProductDraftStateMachineTransitionInterface $productDraftStateMachineTransition, + ListingInterface $productListing, + DraftInterface $productDraft + ): void { + $productListing->canBeVerified()->willReturn(true); + $productListing->getLatestDraft()->willReturn($productDraft); + + $productDraftStateMachineTransition->applyIfCan($productDraft, DraftTransitions::TRANSITION_SEND_TO_VERIFICATION) + ->shouldBeCalled(); + + $this->__invoke($productListing)->shouldReturn($productListing); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/DataProvider/CustomerItemDataProviderSpec.php b/OpenMarketplace/spec/Component/Core/Api/DataProvider/CustomerItemDataProviderSpec.php new file mode 100644 index 0000000..5e27083 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/DataProvider/CustomerItemDataProviderSpec.php @@ -0,0 +1,91 @@ +beConstructedWith( + $baseCustomerItemDataProvider, + $customerRepository, + $sectionProvider, + $vendorContext, + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(CustomerItemDataProvider::class); + $this->shouldHaveType(ItemDataProviderInterface::class); + $this->shouldHaveType(RestrictedDataProviderInterface::class); + } + + public function it_run_base_if_logged_in_is_not_vendor( + ItemDataProviderInterface $baseCustomerItemDataProvider, + CustomerInterface $customer, + VendorContextInterface $vendorContext, + ): void { + $vendorContext->getVendor()->willReturn(null); + $baseCustomerItemDataProvider->getItem('test', 1, 'get', [])->willReturn($customer); + + $this->getItem('test', 1, 'get')->shouldReturn($customer); + } + + public function it_run_base_if_logged_in_is_vendor_and_shop_section( + ItemDataProviderInterface $baseCustomerItemDataProvider, + CustomerInterface $customer, + VendorContextInterface $vendorContext, + VendorInterface $vendor, + SectionProviderInterface $sectionProvider, + ShopApiSection $section, + ): void { + $vendorContext->getVendor()->willReturn($vendor); + $sectionProvider->getSection()->willReturn($section); + $baseCustomerItemDataProvider->getItem('test', 1, 'get', [])->willReturn($customer); + + $this->getItem('test', 1, 'get')->shouldReturn($customer); + } + + public function it_return_customers_vendor_if_logged_in_is_vendor_and_vendor_shop_section( + ItemDataProviderInterface $baseCustomerItemDataProvider, + CustomerInterface $customer, + CustomerRepositoryInterface $customerRepository, + VendorContextInterface $vendorContext, + VendorInterface $vendor, + SectionProviderInterface $sectionProvider, + ShopVendorApiSection $section, + ): void { + $vendorContext->getVendor()->willReturn($vendor); + $sectionProvider->getSection()->willReturn($section); + $customerRepository->findCustomerForVendor($vendor, '1')->willReturn($customer); + + $this->getItem('test', 1, 'get')->shouldReturn($customer); + + $baseCustomerItemDataProvider->getItem('test', 1, 'get', [])->shouldNotHaveBeenCalled(); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/DataProvider/VendorAccountItemDataProviderSpec.php b/OpenMarketplace/spec/Component/Core/Api/DataProvider/VendorAccountItemDataProviderSpec.php new file mode 100644 index 0000000..2bd5371 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/DataProvider/VendorAccountItemDataProviderSpec.php @@ -0,0 +1,133 @@ +beConstructedWith($vendorContext, $vendorRepository, $sectionProvider); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(VendorAccountItemDataProvider::class); + $this->shouldImplement(RestrictedDataProviderInterface::class); + $this->shouldImplement(ItemDataProviderInterface::class); + } + + public function it_supports_vendor_class(): void + { + $this->supports(Vendor::class)->shouldReturn(true); + } + + public function it_provides_vendor_for_shop_api_section_and_without_vendor_context( + SectionProviderInterface $sectionProvider, + ShopApiSection $shopApiSection, + VendorContextInterface $vendorContext, + VendorInterface $vendor, + VendorRepositoryInterface $vendorRepository, + UuidInterface $uuid + ): void { + $sectionProvider->getSection()->willReturn($shopApiSection); + $vendorContext->getVendor()->willReturn(null); + + $vendorRepository->findOneBy(['uuid' => $uuid])->willReturn($vendor); + + $this->getItem(VendorInterface::class, $uuid)->shouldReturn($vendor); + } + + public function it_provides_vendor_for_shop_api_section_and_user_with_other_vendor_context( + SectionProviderInterface $sectionProvider, + ShopApiSection $shopApiSection, + VendorContextInterface $vendorContext, + VendorInterface $vendor, + VendorRepositoryInterface $vendorRepository, + UuidInterface $uuid + ): void { + $sectionProvider->getSection()->willReturn($shopApiSection); + $vendorContext->getVendor()->willReturn($vendor); + $vendor->getUuid()->shouldNotBeCalled(); + $uuid->equals($uuid)->shouldNotBeCalled(); + + $vendorRepository->findOneBy(['uuid' => $uuid])->willReturn($vendor); + + $this->getItem(VendorInterface::class, $uuid)->shouldReturn($vendor); + } + + public function it_provides_null_for_shop_vendor_api_section_and_shop_user_without_vendor_context( + SectionProviderInterface $sectionProvider, + ShopVendorApiSection $shopVendorApiSection, + VendorContextInterface $vendorContext, + VendorRepositoryInterface $vendorRepository, + UuidInterface $uuid + ): void { + $sectionProvider->getSection()->willReturn($shopVendorApiSection); + $vendorContext->getVendor()->willReturn(null); + + $vendorRepository->findOneBy(['uuid' => $uuid])->shouldNotBeCalled(); + + $this->getItem(VendorInterface::class, $uuid)->shouldReturn(null); + } + + public function it_provides_null_for_shop_vendor_api_section_and_user_with_other_vendor_context( + SectionProviderInterface $sectionProvider, + ShopVendorApiSection $shopVendorApiSection, + VendorContextInterface $vendorContext, + VendorInterface $vendor, + VendorRepositoryInterface $vendorRepository, + UuidInterface $uuid + ): void { + $sectionProvider->getSection()->willReturn($shopVendorApiSection); + $vendorContext->getVendor()->willReturn($vendor); + $vendor->getUuid()->willReturn($uuid); + $uuid->equals($uuid)->willReturn(false); + + $vendorRepository->findOneBy(['uuid' => $uuid])->shouldNotBeCalled(); + + $this->getItem(VendorInterface::class, $uuid)->shouldReturn(null); + } + + public function it_provides_vendor_for_shop_vendor_api_section_and_user_with_same_vendor_context( + SectionProviderInterface $sectionProvider, + ShopVendorApiSection $shopVendorApiSection, + VendorContextInterface $vendorContext, + VendorInterface $vendor, + VendorRepositoryInterface $vendorRepository, + UuidInterface $uuid + ): void { + $sectionProvider->getSection()->willReturn($shopVendorApiSection); + $vendorContext->getVendor()->willReturn($vendor); + $vendor->getUuid()->willReturn($uuid); + $uuid->equals($uuid)->willReturn(true); + + $vendorRepository->findOneBy(['uuid' => $uuid])->willReturn($vendor); + + $this->getItem(VendorInterface::class, $uuid)->shouldReturn($vendor); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/DataTransformer/ProductDraftAwareCommandDataTransformerSpec.php b/OpenMarketplace/spec/Component/Core/Api/DataTransformer/ProductDraftAwareCommandDataTransformerSpec.php new file mode 100644 index 0000000..c3a1b85 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/DataTransformer/ProductDraftAwareCommandDataTransformerSpec.php @@ -0,0 +1,97 @@ +beConstructedWith($requestStack, $draftImageFactory); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(ProductDraftAwareCommandDataTransformer::class); + } + + public function it_supports_product_draft_aware_interface( + ProductDraftAwareInterface $productDraftAware + ): void { + $this->supportsTransformation($productDraftAware)->shouldReturn(true); + } + + public function it_does_nothing_when_there_is_no_product_draft_assigned( + ProductDraftAwareInterface $productDraftAware, + RequestStack $requestStack + ): void { + $productDraftAware->getProductDraft()->willReturn(null); + + $requestStack->getCurrentRequest()->shouldNotBeCalled(); + + $this->transform($productDraftAware, ''); + } + + public function it_does_nothing_when_there_is_no_images_in_request( + ProductDraftAwareInterface $productDraftAware, + Draft $productDraft, + DraftImageFactoryInterface $draftImageFactory, + RequestStack $requestStack, + Request $request + ): void { + $productDraftAware->getProductDraft()->willReturn($productDraft); + $request->files = new FileBag(); + $requestStack->getCurrentRequest()->willReturn($request); + + $productDraft->getImages()->shouldNotBeCalled(); + $draftImageFactory->createNew()->shouldNotBeCalled(); + + $this->transform($productDraftAware, ''); + } + + public function it_sets_images_when_there_is_one_in_request( + ProductDraftAwareInterface $productDraftAware, + Draft $productDraft, + DraftImageFactoryInterface $draftImageFactory, + RequestStack $requestStack, + Request $request, + ImageInterface $draftImage, + Collection $imagesCollection + ): void { + $productDraftAware->getProductDraft()->willReturn($productDraft); + $imageFile = new UploadedFile(__FILE__, 'test'); + $request->files = new FileBag(['images' => [$imageFile]]); + $requestStack->getCurrentRequest()->willReturn($request); + + $productDraft->getImages()->willReturn($imagesCollection); + $imagesCollection->clear()->shouldBeCalled(); + $draftImageFactory->createNew()->willReturn($draftImage); + + $draftImage->setFile($imageFile)->shouldBeCalled(); + $productDraft->addImage($draftImage)->shouldBeCalled(); + + $this->transform($productDraftAware, ''); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/DataTransformer/ProductListingAwareCommandDataTransformerSpec.php b/OpenMarketplace/spec/Component/Core/Api/DataTransformer/ProductListingAwareCommandDataTransformerSpec.php new file mode 100644 index 0000000..86386a3 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/DataTransformer/ProductListingAwareCommandDataTransformerSpec.php @@ -0,0 +1,56 @@ +shouldHaveType(ProductListingAwareCommandDataTransformer::class); + } + + public function it_supports_shop_user_aware_interface( + ProductListingAwareInterface $productListingAware + ): void { + $this->supportsTransformation($productListingAware)->shouldReturn(true); + } + + public function it_does_nothing_when_product_listing_is_already_assigned( + ProductListingAwareInterface $productListingAware, + ListingInterface $productListing + ): void { + $productListingAware->getProductListing()->willReturn($productListing); + $this->supportsTransformation($productListingAware)->shouldReturn(true); + + $productListingAware->setProductListing(Argument::any())->shouldNotBeCalled(); + $this->transform($productListingAware, ''); + } + + public function it_sets_product_listing_when_there_is_one_in_context( + ProductListingAwareInterface $productListingAware, + ListingInterface $productListing + ): void { + $productListingAware->getProductListing()->willReturn(null); + $this->supportsTransformation($productListingAware)->shouldReturn(true); + + $productListingAware->setProductListing($productListing)->shouldBeCalled(); + $this->transform($productListingAware, '', [ + 'object_to_populate' => $productListing, + ]); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/DataTransformer/ResourceIdAwareCommandDataTransformerSpec.php b/OpenMarketplace/spec/Component/Core/Api/DataTransformer/ResourceIdAwareCommandDataTransformerSpec.php new file mode 100644 index 0000000..34d9cdd --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/DataTransformer/ResourceIdAwareCommandDataTransformerSpec.php @@ -0,0 +1,72 @@ +beConstructedWith($requestStack); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(ResourceIdAwareCommandDataTransformer::class); + } + + public function it_supports_resource_id_aware_interface( + ResourceIdAwareInterface $resourceIdAware + ): void { + $this->supportsTransformation($resourceIdAware)->shouldReturn(true); + } + + public function it_throws_exception_when_there_isnt_id_in_request( + ResourceIdAwareInterface $resourceIdAware, + RequestStack $requestStack, + Request $request + ): void { + $resourceIdAware->getResourceIdAttributeKey()->willReturn('id'); + $request->attributes = new ParameterBag(); + $requestStack->getCurrentRequest()->willReturn($request); + + $this->supportsTransformation($resourceIdAware)->shouldReturn(true); + + $this + ->shouldThrow(\InvalidArgumentException::class) + ->during('transform', [$resourceIdAware, '']) + ; + } + + public function it_sets_resource_id_from_request( + ResourceIdAwareInterface $resourceIdAware, + RequestStack $requestStack, + Request $request + ): void { + $resourceIdAware->getResourceIdAttributeKey()->willReturn('id'); + $request->attributes = new ParameterBag(['id' => '1']); + $requestStack->getCurrentRequest()->willReturn($request); + + $this->supportsTransformation($resourceIdAware)->shouldReturn(true); + + $resourceIdAware->setResourceId('1')->shouldBeCalled(); + + $this->transform($resourceIdAware, ''); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/DataTransformer/ShopUserAwareInputCommandDataTransformerSpec.php b/OpenMarketplace/spec/Component/Core/Api/DataTransformer/ShopUserAwareInputCommandDataTransformerSpec.php new file mode 100644 index 0000000..88a0b11 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/DataTransformer/ShopUserAwareInputCommandDataTransformerSpec.php @@ -0,0 +1,80 @@ +beConstructedWith($userContext); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(ShopUserAwareInputCommandDataTransformer::class); + $this->shouldImplement(CommandDataTransformerInterface::class); + } + + public function it_supports_shop_user_aware_interface( + ShopUserAwareInterface $shopUserAware + ): void { + $this->supportsTransformation($shopUserAware)->shouldReturn(true); + } + + public function it_set_shop_user_from_context( + ShopUserAwareInterface $shopUserAware, + UserContextInterface $userContext, + ShopUserInterface $shopUser + ): void { + $shopUserAware->getShopUser()->willReturn(null); + $userContext->getUser()->willReturn($shopUser); + + $shopUserAware->setShopUser($shopUser)->shouldBeCalled(); + + $this->transform($shopUserAware, ''); + } + + public function it_does_nothing_if_user_is_not_shop_user_context( + ShopUserAwareInterface $shopUserAware, + UserContextInterface $userContext, + UserInterface $user + ): void { + $shopUserAware->getShopUser()->willReturn(null); + $userContext->getUser()->willReturn($user); + + $shopUserAware->setShopUser($user)->shouldNotBeCalled(); + + $this->transform($shopUserAware, ''); + } + + public function it_does_nothing_if_shop_user_already_set( + ShopUserAwareInterface $shopUserAware, + UserContextInterface $userContext, + ShopUserInterface $shopUser + ): void { + $shopUserAware->getShopUser()->willReturn($shopUser); + $userContext->getUser()->willReturn($shopUser); + + $shopUserAware->setShopUser($shopUser)->shouldNotBeCalled(); + + $this->transform($shopUserAware, ''); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/DataTransformer/VendorImageFileAwareCommandDataTransformerSpec.php b/OpenMarketplace/spec/Component/Core/Api/DataTransformer/VendorImageFileAwareCommandDataTransformerSpec.php new file mode 100644 index 0000000..0f41409 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/DataTransformer/VendorImageFileAwareCommandDataTransformerSpec.php @@ -0,0 +1,68 @@ +beConstructedWith($requestStack); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(VendorImageFileAwareCommandDataTransformer::class); + } + + public function it_supports_shop_user_aware_interface( + VendorImageFileAwareInterface $vendorImageFileAware + ): void { + $this->supportsTransformation($vendorImageFileAware)->shouldReturn(true); + } + + public function it_does_nothing_when_there_is_no_file_in_request( + VendorImageFileAwareInterface $vendorImageFileAware, + RequestStack $requestStack, + Request $request, + ): void { + $request->files = new FileBag(); + $requestStack->getCurrentRequest()->willReturn($request); + + $vendorImageFileAware->setFile(Argument::any())->shouldNotBeCalled(); + + $this->transform($vendorImageFileAware, ''); + } + + public function it_sets_the_file_when_there_is_one_in_request( + VendorImageFileAwareInterface $vendorImageFileAware, + RequestStack $requestStack, + Request $request + ): void { + $file = new UploadedFile(__FILE__, 'test'); + $request->files = new FileBag(['file' => $file]); + $requestStack->getCurrentRequest()->willReturn($request); + + $vendorImageFileAware->setFile($file)->shouldBeCalled(); + + $this->transform($vendorImageFileAware, ''); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/DataTransformer/VendorImageOwnerAwareCommandDataTransformerSpec.php b/OpenMarketplace/spec/Component/Core/Api/DataTransformer/VendorImageOwnerAwareCommandDataTransformerSpec.php new file mode 100644 index 0000000..3d5fda6 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/DataTransformer/VendorImageOwnerAwareCommandDataTransformerSpec.php @@ -0,0 +1,82 @@ +beConstructedWith($userContext); + } + + public function it_is_initializable() + { + $this->shouldHaveType(VendorImageOwnerAwareCommandDataTransformer::class); + } + + public function it_supports_shop_user_aware_interface( + VendorImageOwnerAwareInterface $ownerAware + ): void { + $this->supportsTransformation($ownerAware)->shouldReturn(true); + } + + public function it_does_nothing_when_owner_already_exist( + VendorImageOwnerAwareInterface $ownerAware, + UserContextInterface $userContext, + VendorInterface $vendor, + UserInterface $user, + ): void { + $ownerAware->getOwner()->willReturn($vendor); + + $ownerAware->setOwner(Argument::any())->shouldNotBeCalled(); + + $this->transform($ownerAware, ''); + } + + public function it_does_nothing_when_there_is_no_shop_user_context( + VendorImageOwnerAwareInterface $ownerAware, + UserContextInterface $userContext, + UserInterface $user + ): void { + $userContext->getUser()->willReturn($user); + $ownerAware->getOwner()->willReturn(null); + + $ownerAware->setOwner(Argument::any())->shouldNotBeCalled(); + + $this->transform($ownerAware, ''); + } + + public function it_sets_owner_when_there_is_shop_user_context( + VendorImageOwnerAwareInterface $ownerAware, + UserContextInterface $userContext, + ShopUserInterface $user, + VendorInterface $vendor + ): void { + $user->getVendor()->willReturn($vendor); + $userContext->getUser()->willReturn($user); + $ownerAware->getOwner()->willReturn(null); + + $ownerAware->setOwner($vendor)->shouldBeCalled(); + + $this->transform($ownerAware, ''); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Doctrine/QueryCollectionExtension/OrdersByLoggedInUserExtensionSpec.php b/OpenMarketplace/spec/Component/Core/Api/Doctrine/QueryCollectionExtension/OrdersByLoggedInUserExtensionSpec.php new file mode 100644 index 0000000..9ff5832 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Doctrine/QueryCollectionExtension/OrdersByLoggedInUserExtensionSpec.php @@ -0,0 +1,150 @@ +beConstructedWith($baseOrdersByLoggedInUserExtension, $sectionProvider, $userContext); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(OrdersByLoggedInUserExtension::class); + $this->shouldHaveType(ContextAwareQueryCollectionExtensionInterface::class); + } + + public function it_does_not_filter_for_not_supported_class( + ContextAwareQueryCollectionExtensionInterface $baseOrdersByLoggedInUserExtension, + SectionProviderInterface $sectionProvider, + QueryBuilder $queryBuilder, + LegacyQueryNameGeneratorInterface $queryNameGenerator + ): void { + $this->applyToCollection( + $queryBuilder, + $queryNameGenerator, + ProductInterface::class + ); + + $sectionProvider->getSection()->shouldNotHaveBeenCalled(); + $baseOrdersByLoggedInUserExtension->applyToCollection( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + null, + [] + )->shouldNotHaveBeenCalled(); + } + + public function it_does_not_filter_if_shop_vendor_api_section( + ContextAwareQueryCollectionExtensionInterface $baseOrdersByLoggedInUserExtension, + SectionProviderInterface $sectionProvider, + ShopVendorApiSection $shopVendorApiSection, + QueryBuilder $queryBuilder, + LegacyQueryNameGeneratorInterface $queryNameGenerator + ): void { + $sectionProvider->getSection()->willReturn($shopVendorApiSection); + + $this->applyToCollection( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class + ); + + $baseOrdersByLoggedInUserExtension->applyToCollection( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + null, + [] + )->shouldNotHaveBeenCalled(); + } + + public function it_filters_if_not_shop_vendor_api_section_and_it_is_logged_in_admin_user( + ContextAwareQueryCollectionExtensionInterface $baseOrdersByLoggedInUserExtension, + SectionProviderInterface $sectionProvider, + ShopApiSection $shopApiSection, + UserContextInterface $userContext, + AdminUserInterface $user, + QueryBuilder $queryBuilder, + LegacyQueryNameGeneratorInterface $queryNameGenerator + ): void { + $sectionProvider->getSection()->willReturn($shopApiSection); + $userContext->getUser()->willReturn($user); + + $this->applyToCollection( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class + ); + + $queryBuilder->getRootAliases()->shouldNotHaveBeenCalled(); + $queryBuilder->andWhere(Argument::any())->shouldNotHaveBeenCalled(); + $baseOrdersByLoggedInUserExtension->applyToCollection( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + null, + [] + )->shouldHaveBeenCalled(); + } + + public function it_filters_if_not_shop_vendor_api_section_and_it_is_logged_in_shop_user( + ContextAwareQueryCollectionExtensionInterface $baseOrdersByLoggedInUserExtension, + SectionProviderInterface $sectionProvider, + ShopApiSection $shopApiSection, + UserContextInterface $userContext, + ShopUserInterface $user, + QueryBuilder $queryBuilder, + LegacyQueryNameGeneratorInterface $queryNameGenerator + ): void { + $sectionProvider->getSection()->willReturn($shopApiSection); + $userContext->getUser()->willReturn($user); + $queryBuilder->getRootAliases()->willReturn(['root']); + $queryBuilder->andWhere(Argument::any())->willReturn($queryBuilder); + + $this->applyToCollection( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class + ); + + $queryBuilder->andWhere('root.mode != :primaryMode')->shouldHaveBeenCalled(); + $queryBuilder->setParameter('primaryMode', OrderInterface::PRIMARY_ORDER_MODE)->shouldHaveBeenCalled(); + + $baseOrdersByLoggedInUserExtension->applyToCollection( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + null, + [] + )->shouldHaveBeenCalled(); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextExtensionSpec.php b/OpenMarketplace/spec/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextExtensionSpec.php new file mode 100644 index 0000000..96ae0af --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextExtensionSpec.php @@ -0,0 +1,106 @@ +beConstructedWith([$filterVendorStrategy], $vendorContext, $sectionProvider); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(VendorContextExtension::class); + $this->shouldHaveType(QueryCollectionExtensionInterface::class); + } + + public function it_does_nothing_for_collection_when_strategy_does_not_support_class( + FilterVendorStrategy $filterVendorStrategy, + SectionProviderInterface $sectionProvider, + VendorContextInterface $vendorContext, + QueryBuilder $queryBuilder, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $filterVendorStrategy->supports(VendorInterface::class)->willReturn(false); + + $this->applyToCollection($queryBuilder, $queryNameGenerator, VendorInterface::class); + + $sectionProvider->getSection()->shouldNotHaveBeenCalled(); + $vendorContext->getVendor()->shouldNotHaveBeenCalled(); + } + + public function it_does_nothing_for_collection_when_section_in_not_shop_vendor_api( + FilterVendorStrategy $filterVendorStrategy, + SectionProviderInterface $sectionProvider, + ShopApiSection $shopApiSection, + VendorContextInterface $vendorContext, + QueryBuilder $queryBuilder, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $filterVendorStrategy->supports(VendorInterface::class)->willReturn(true); + $sectionProvider->getSection()->willReturn($shopApiSection); + + $this->applyToCollection($queryBuilder, $queryNameGenerator, VendorInterface::class); + + $vendorContext->getVendor()->shouldNotHaveBeenCalled(); + } + + public function it_prevents_returning_any_records_for_collection_when_current_user_is_not_vendor_context( + FilterVendorStrategy $filterVendorStrategy, + SectionProviderInterface $sectionProvider, + ShopVendorApiSection $shopVendorApiSection, + VendorContextInterface $vendorContext, + QueryBuilder $queryBuilder, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $filterVendorStrategy->supports(VendorInterface::class)->willReturn(true); + $sectionProvider->getSection()->willReturn($shopVendorApiSection); + $vendorContext->getVendor()->willReturn(null); + + $this->applyToCollection($queryBuilder, $queryNameGenerator, VendorInterface::class); + + $queryBuilder->andWhere('1=0')->shouldHaveBeenCalled(); + } + + public function it_filters_resources_by_current_vendor( + FilterVendorStrategy $filterVendorStrategy, + SectionProviderInterface $sectionProvider, + ShopVendorApiSection $shopVendorApiSection, + VendorContextInterface $vendorContext, + VendorInterface $vendor, + QueryBuilder $queryBuilder, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $filterVendorStrategy->supports(VendorInterface::class)->willReturn(true); + $sectionProvider->getSection()->willReturn($shopVendorApiSection); + $vendorContext->getVendor()->willReturn($vendor); + + $this->applyToCollection($queryBuilder, $queryNameGenerator, VendorInterface::class); + + $filterVendorStrategy->filterByVendor($queryBuilder, $vendor)->shouldHaveBeenCalled(); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Doctrine/QueryItemExtension/OrderGetMethodItemExtensionSpec.php b/OpenMarketplace/spec/Component/Core/Api/Doctrine/QueryItemExtension/OrderGetMethodItemExtensionSpec.php new file mode 100644 index 0000000..045f0a0 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Doctrine/QueryItemExtension/OrderGetMethodItemExtensionSpec.php @@ -0,0 +1,158 @@ +beConstructedWith($baseOrderGetMethodItemExtension, $sectionProvider, $userContext); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(OrderGetMethodItemExtension::class); + $this->shouldHaveType(QueryItemExtensionInterface::class); + } + + public function it_does_not_filter_for_not_supported_class( + QueryItemExtensionInterface $baseOrderGetMethodItemExtension, + SectionProviderInterface $sectionProvider, + QueryBuilder $queryBuilder, + LegacyQueryNameGeneratorInterface $queryNameGenerator + ): void { + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + ProductInterface::class, + ['id'] + ); + + $sectionProvider->getSection()->shouldNotHaveBeenCalled(); + $baseOrderGetMethodItemExtension->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['id'], + null, + [] + )->shouldNotHaveBeenCalled(); + } + + public function it_does_not_filter_if_shop_vendor_api_section( + QueryItemExtensionInterface $baseOrderGetMethodItemExtension, + SectionProviderInterface $sectionProvider, + ShopVendorApiSection $shopVendorApiSection, + QueryBuilder $queryBuilder, + LegacyQueryNameGeneratorInterface $queryNameGenerator + ): void { + $sectionProvider->getSection()->willReturn($shopVendorApiSection); + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['id'] + ); + + $baseOrderGetMethodItemExtension->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['id'], + null, + [] + )->shouldNotHaveBeenCalled(); + } + + public function it_filters_if_not_shop_vendor_api_section_and_it_is_logged_in_admin_user( + QueryItemExtensionInterface $baseOrderGetMethodItemExtension, + SectionProviderInterface $sectionProvider, + ShopApiSection $shopApiSection, + UserContextInterface $userContext, + AdminUserInterface $user, + QueryBuilder $queryBuilder, + LegacyQueryNameGeneratorInterface $queryNameGenerator + ): void { + $sectionProvider->getSection()->willReturn($shopApiSection); + $userContext->getUser()->willReturn($user); + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['id'] + ); + + $queryBuilder->getRootAliases()->shouldNotHaveBeenCalled(); + $queryBuilder->andWhere(Argument::any())->shouldNotHaveBeenCalled(); + $baseOrderGetMethodItemExtension->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['id'], + null, + [] + )->shouldHaveBeenCalled(); + } + + public function it_filters_if_not_shop_vendor_api_section_and_it_is_logged_in_shop_user( + QueryItemExtensionInterface $baseOrderGetMethodItemExtension, + SectionProviderInterface $sectionProvider, + ShopApiSection $shopApiSection, + UserContextInterface $userContext, + ShopUserInterface $user, + QueryBuilder $queryBuilder, + LegacyQueryNameGeneratorInterface $queryNameGenerator + ): void { + $sectionProvider->getSection()->willReturn($shopApiSection); + $userContext->getUser()->willReturn($user); + $queryBuilder->getRootAliases()->willReturn(['root']); + $queryBuilder->andWhere(Argument::any())->willReturn($queryBuilder); + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['id'] + ); + + $queryBuilder->andWhere('root.mode != :primaryMode')->shouldHaveBeenCalled(); + $queryBuilder->setParameter('primaryMode', OrderInterface::PRIMARY_ORDER_MODE)->shouldHaveBeenCalled(); + + $baseOrderGetMethodItemExtension->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['id'], + null, + [] + )->shouldHaveBeenCalled(); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Doctrine/QueryItemExtension/OrderMethodsItemExtensionSpec.php b/OpenMarketplace/spec/Component/Core/Api/Doctrine/QueryItemExtension/OrderMethodsItemExtensionSpec.php new file mode 100644 index 0000000..c7acf5f --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Doctrine/QueryItemExtension/OrderMethodsItemExtensionSpec.php @@ -0,0 +1,158 @@ +beConstructedWith($baseOrderMethodsItemExtension, $sectionProvider, $userContext); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(OrderMethodsItemExtension::class); + $this->shouldHaveType(QueryItemExtensionInterface::class); + } + + public function it_does_not_filter_for_not_supported_class( + QueryItemExtensionInterface $baseOrderGetMethodItemExtension, + SectionProviderInterface $sectionProvider, + QueryBuilder $queryBuilder, + LegacyQueryNameGeneratorInterface $queryNameGenerator + ): void { + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + ProductInterface::class, + ['id'] + ); + + $sectionProvider->getSection()->shouldNotHaveBeenCalled(); + $baseOrderGetMethodItemExtension->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['id'], + null, + [] + )->shouldNotHaveBeenCalled(); + } + + public function it_does_not_filter_if_shop_vendor_api_section( + QueryItemExtensionInterface $baseOrderMethodsItemExtension, + SectionProviderInterface $sectionProvider, + ShopVendorApiSection $shopVendorApiSection, + QueryBuilder $queryBuilder, + LegacyQueryNameGeneratorInterface $queryNameGenerator + ): void { + $sectionProvider->getSection()->willReturn($shopVendorApiSection); + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['id'] + ); + + $baseOrderMethodsItemExtension->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['id'], + null, + [] + )->shouldNotHaveBeenCalled(); + } + + public function it_filters_if_not_shop_vendor_api_section_and_it_is_logged_in_admin_user( + QueryItemExtensionInterface $baseOrderMethodsItemExtension, + SectionProviderInterface $sectionProvider, + ShopApiSection $shopApiSection, + UserContextInterface $userContext, + AdminUserInterface $user, + QueryBuilder $queryBuilder, + LegacyQueryNameGeneratorInterface $queryNameGenerator + ): void { + $sectionProvider->getSection()->willReturn($shopApiSection); + $userContext->getUser()->willReturn($user); + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['id'] + ); + + $queryBuilder->getRootAliases()->shouldNotHaveBeenCalled(); + $queryBuilder->andWhere(Argument::any())->shouldNotHaveBeenCalled(); + $baseOrderMethodsItemExtension->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['id'], + null, + [] + )->shouldHaveBeenCalled(); + } + + public function it_filters_if_not_shop_vendor_api_section_and_it_is_logged_in_shop_user( + QueryItemExtensionInterface $baseOrderMethodsItemExtension, + SectionProviderInterface $sectionProvider, + ShopApiSection $shopApiSection, + UserContextInterface $userContext, + ShopUserInterface $user, + QueryBuilder $queryBuilder, + LegacyQueryNameGeneratorInterface $queryNameGenerator + ): void { + $sectionProvider->getSection()->willReturn($shopApiSection); + $userContext->getUser()->willReturn($user); + $queryBuilder->getRootAliases()->willReturn(['root']); + $queryBuilder->andWhere(Argument::any())->willReturn($queryBuilder); + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['id'] + ); + + $queryBuilder->andWhere('root.mode != :primaryMode')->shouldHaveBeenCalled(); + $queryBuilder->setParameter('primaryMode', OrderInterface::PRIMARY_ORDER_MODE)->shouldHaveBeenCalled(); + + $baseOrderMethodsItemExtension->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['id'], + null, + [] + )->shouldHaveBeenCalled(); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/EventSubscriber/UuidSubscriberSpec.php b/OpenMarketplace/spec/Component/Core/Api/EventSubscriber/UuidSubscriberSpec.php new file mode 100644 index 0000000..cc79e6c --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/EventSubscriber/UuidSubscriberSpec.php @@ -0,0 +1,114 @@ +beConstructedWith($uuidGenerator); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(UuidSubscriber::class); + } + + public function it_updates_uuid_on_pre_persist_doctrine_event( + UuidGenerator $uuidGenerator, + LifecycleEventArgs $event, + EntityManager $objectManager, + UuidAwareInterface $uuidAware, + UuidInterface $uuid + ): void { + $uuidAware->getUuid()->willReturn(null); + $event->getObject()->willReturn($uuidAware); + $event->getObjectManager()->willReturn($objectManager); + + $uuidGenerator->generate($objectManager, $uuidAware)->shouldBeCalled()->willReturn($uuid); + $uuidAware->setUuid($uuid)->shouldBeCalled(); + + $this->prePersist($event); + } + + public function it_updates_uuid_on_pre_update_doctrine_event( + UuidGenerator $uuidGenerator, + LifecycleEventArgs $event, + EntityManager $objectManager, + UuidAwareInterface $uuidAware, + UuidInterface $uuid + ): void { + $uuidAware->getUuid()->willReturn(null); + $event->getObject()->willReturn($uuidAware); + $event->getObjectManager()->willReturn($objectManager); + + $uuidGenerator->generate($objectManager, $uuidAware)->shouldBeCalled()->willReturn($uuid); + $uuidAware->setUuid($uuid)->shouldBeCalled(); + + $this->preUpdate($event); + } + + public function it_does_nothing_if_uuid_already_set_on_pre_update_doctrine_event( + UuidGenerator $uuidGenerator, + LifecycleEventArgs $event, + EntityManager $objectManager, + UuidAwareInterface $uuidAware, + UuidInterface $uuid + ): void { + $uuidAware->getUuid()->willReturn($uuid); + $event->getObject()->willReturn($uuidAware); + $event->getObjectManager()->willReturn($objectManager); + + $uuidGenerator->generate($objectManager, $uuidAware)->shouldNotBeCalled(); + $uuidAware->setUuid($uuid)->shouldNotBeCalled(); + + $this->preUpdate($event); + } + + public function it_does_nothing_if_object_is_not_uuid_aware_on_pre_persist_doctrine_event( + UuidGenerator $uuidGenerator, + LifecycleEventArgs $event, + EntityManager $objectManager, + stdClass $object, + ): void { + $event->getObject()->willReturn($object); + $event->getObjectManager()->willReturn($objectManager); + + $uuidGenerator->generate($objectManager, $object)->shouldNotBeCalled(); + + $this->prePersist($event); + } + + public function it_does_nothing_if_object_is_not_uuid_aware_on_pre_update_doctrine_event( + UuidGenerator $uuidGenerator, + LifecycleEventArgs $event, + EntityManager $objectManager, + stdClass $object, + ): void { + $event->getObject()->willReturn($object); + $event->getObjectManager()->willReturn($objectManager); + + $uuidGenerator->generate($objectManager, $object)->shouldNotBeCalled(); + + $this->preUpdate($event); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/EventSubscriber/VendorAwareEventSubscriberSpec.php b/OpenMarketplace/spec/Component/Core/Api/EventSubscriber/VendorAwareEventSubscriberSpec.php new file mode 100644 index 0000000..e2d479e --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/EventSubscriber/VendorAwareEventSubscriberSpec.php @@ -0,0 +1,112 @@ +beConstructedWith($vendorContext); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(VendorAwareEventSubscriber::class); + } + + public function it_does_nothing_when_current_resource_is_not_a_vendor_aware( + VendorContextInterface $vendorContext, + VendorInterface $vendor, + VendorAwareInterface $resource, + HttpKernelInterface $kernel, + Request $request, + ): void { + $vendorContext->getVendor()->shouldNotBeCalled(); + $resource->setVendor($vendor)->shouldNotBeCalled(); + + $this->setVendorFromCurrentContext(new ViewEvent( + $kernel->getWrappedObject(), + $request->getWrappedObject(), + HttpKernelInterface::MAIN_REQUEST, + $vendor->getWrappedObject(), + )); + } + + public function it_does_nothing_when_request_method_is_different_than_post( + VendorContextInterface $vendorContext, + VendorInterface $vendor, + VendorAwareInterface $resource, + HttpKernelInterface $kernel, + Request $request, + ): void { + $request->getMethod()->willReturn(Request::METHOD_GET); + $vendorContext->getVendor()->willReturn($vendor); + $resource->setVendor($vendor)->shouldNotBeCalled(); + + $this->setVendorFromCurrentContext(new ViewEvent( + $kernel->getWrappedObject(), + $request->getWrappedObject(), + HttpKernelInterface::MAIN_REQUEST, + $resource->getWrappedObject(), + )); + } + + public function it_does_nothing_when_current_user_is_not_vendor_context( + VendorContextInterface $vendorContext, + VendorInterface $vendor, + VendorAwareInterface $resource, + HttpKernelInterface $kernel, + Request $request, + ): void { + $request->getMethod()->willReturn(Request::METHOD_POST); + $vendorContext->getVendor()->willReturn(null); + $resource->setVendor($vendor)->shouldNotBeCalled(); + + $this->setVendorFromCurrentContext(new ViewEvent( + $kernel->getWrappedObject(), + $request->getWrappedObject(), + HttpKernelInterface::MAIN_REQUEST, + $resource->getWrappedObject(), + )); + } + + public function it_set_vendor_from_current_context( + VendorContextInterface $vendorContext, + VendorInterface $vendor, + VendorAwareInterface $resource, + HttpKernelInterface $kernel, + Request $request + ): void { + $request->getMethod()->willReturn(Request::METHOD_POST); + $vendorContext->getVendor()->willReturn($vendor); + + $vendorContext->getVendor()->shouldBeCalled(); + $resource->setVendor($vendor)->shouldBeCalled(); + + $this->setVendorFromCurrentContext(new ViewEvent( + $kernel->getWrappedObject(), + $request->getWrappedObject(), + HttpKernelInterface::MAIN_REQUEST, + $resource->getWrappedObject(), + )); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/EventSubscriber/VendorSlugEventSubscriberSpec.php b/OpenMarketplace/spec/Component/Core/Api/EventSubscriber/VendorSlugEventSubscriberSpec.php new file mode 100644 index 0000000..0eb1936 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/EventSubscriber/VendorSlugEventSubscriberSpec.php @@ -0,0 +1,149 @@ +beConstructedWith($vendorSlugGenerator); + } + + public function it_is_initializable() + { + $this->shouldHaveType(VendorSlugEventSubscriber::class); + $this->shouldImplement(EventSubscriberInterface::class); + } + + public function it_generates_slug_for_vendor_with_company_name_and_empty_slug( + SlugGeneratorInterface $vendorSlugGenerator, + VendorInterface $vendor, + HttpKernelInterface $kernel, + Request $request, + ): void { + $request->getMethod()->willReturn(Request::METHOD_POST); + + $vendor->getCompanyName()->willReturn('Wayne Enterprises'); + $vendor->getSlug()->willReturn(null); + + $vendorSlugGenerator->generateSlug('Wayne Enterprises')->willReturn('Wayne-Enterprises'); + + $vendor->setSlug('Wayne-Enterprises')->shouldBeCalled(); + + $this->generateSlug(new ViewEvent( + $kernel->getWrappedObject(), + $request->getWrappedObject(), + HttpKernelInterface::MAIN_REQUEST, + $vendor->getWrappedObject(), + )); + } + + public function it_generates_slug_for_vendor_slug_aware_with_company_name_and_empty_slug( + SlugGeneratorInterface $vendorSlugGenerator, + VendorSlugAwareInterface $vendorSlugAware, + HttpKernelInterface $kernel, + Request $request, + ): void { + $request->getMethod()->willReturn(Request::METHOD_POST); + + $vendorSlugAware->getCompanyName()->willReturn('Wayne Enterprises'); + $vendorSlugAware->getSlug()->willReturn(null); + + $vendorSlugGenerator->generateSlug('Wayne Enterprises')->willReturn('Wayne-Enterprises'); + + $vendorSlugAware->setSlug('Wayne-Enterprises')->shouldBeCalled(); + + $this->generateSlug(new ViewEvent( + $kernel->getWrappedObject(), + $request->getWrappedObject(), + HttpKernelInterface::MAIN_REQUEST, + $vendorSlugAware->getWrappedObject(), + )); + } + + public function it_generates_new_slug_for_vendor_with_slug_and_company_name( + SlugGeneratorInterface $vendorSlugGenerator, + VendorInterface $vendor, + HttpKernelInterface $kernel, + Request $request, + ): void { + $request->getMethod()->willReturn(Request::METHOD_POST); + + $vendor->getCompanyName()->willReturn('Wayne Enterprises'); + $vendor->getSlug()->willReturn('Prev-Slug'); + + $vendorSlugGenerator->generateSlug('Wayne Enterprises')->willReturn('Wayne-Enterprises'); + + $vendor->setSlug('Wayne-Enterprises')->shouldBeCalled(); + + $this->generateSlug(new ViewEvent( + $kernel->getWrappedObject(), + $request->getWrappedObject(), + HttpKernelInterface::MAIN_REQUEST, + $vendor->getWrappedObject(), + )); + } + + public function it_does_nothing_if_the_vendor_has_no_company_name( + SlugGeneratorInterface $vendorSlugGenerator, + VendorSlugAwareInterface $vendor, + HttpKernelInterface $kernel, + Request $request, + ): void { + $request->getMethod()->willReturn(Request::METHOD_POST); + + $vendor->getCompanyName()->willReturn(null); + + $vendorSlugGenerator->generateSlug(Argument::any())->shouldNotBeCalled(); + $vendor->setSlug(Argument::any())->shouldNotBeCalled(); + + $this->generateSlug(new ViewEvent( + $kernel->getWrappedObject(), + $request->getWrappedObject(), + HttpKernelInterface::MAIN_REQUEST, + $vendor->getWrappedObject(), + )); + } + + public function it_does_nothing_if_the_vendor_has_empty_company_name( + SlugGeneratorInterface $vendorSlugGenerator, + VendorSlugAwareInterface $vendor, + HttpKernelInterface $kernel, + Request $request, + ): void { + $request->getMethod()->willReturn(Request::METHOD_POST); + + $vendor->getCompanyName()->willReturn(''); + + $vendorSlugGenerator->generateSlug(Argument::any())->shouldNotBeCalled(); + $vendor->setSlug(Argument::any())->shouldNotBeCalled(); + + $this->generateSlug(new ViewEvent( + $kernel->getWrappedObject(), + $request->getWrappedObject(), + HttpKernelInterface::MAIN_REQUEST, + $vendor->getWrappedObject(), + )); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Messenger/Command/Vendor/CreateProductListingSpec.php b/OpenMarketplace/spec/Component/Core/Api/Messenger/Command/Vendor/CreateProductListingSpec.php new file mode 100644 index 0000000..7ced535 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Messenger/Command/Vendor/CreateProductListingSpec.php @@ -0,0 +1,39 @@ +shouldHaveType(CreateProductListing::class); + } + + public function it_has_product_draft( + Draft $productDraft + ): void { + $this->setProductDraft($productDraft); + $this->getProductDraft()->shouldReturn($productDraft); + } + + public function it_has_vendor( + VendorInterface $vendor + ): void { + $this->setVendor($vendor); + $this->getVendor()->shouldReturn($vendor); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Messenger/Command/Vendor/RegisterVendorSpec.php b/OpenMarketplace/spec/Component/Core/Api/Messenger/Command/Vendor/RegisterVendorSpec.php new file mode 100644 index 0000000..065bcbf --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Messenger/Command/Vendor/RegisterVendorSpec.php @@ -0,0 +1,77 @@ +beConstructedWith('companyName', 'taxIdentifier', 'iban', 'phoneNumber', 'description', $vendorAddress); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(RegisterVendor::class); + $this->shouldImplement(ShopUserAwareInterface::class); + $this->shouldImplement(VendorSlugAwareInterface::class); + } + + public function it_has_company_name(): void + { + $this->getCompanyName()->shouldReturn('companyName'); + } + + public function it_has_tax_identifier(): void + { + $this->getTaxIdentifier()->shouldReturn('taxIdentifier'); + } + + public function it_has_bank_account_number(): void + { + $this->getBankAccountNumber()->shouldReturn('iban'); + } + + public function it_has_phone_number(): void + { + $this->getPhoneNumber()->shouldReturn('phoneNumber'); + } + + public function it_has_description(): void + { + $this->getDescription()->shouldReturn('description'); + } + + public function it_has_vendor_address(Address $vendorAddress): void + { + $this->getVendorAddress()->shouldReturn($vendorAddress); + } + + public function it_has_slug(): void + { + $this->setSlug('slug'); + $this->getSlug()->shouldReturn('slug'); + } + + public function it_has_shop_user(ShopUserInterface $shopUser): void + { + $this->setShopUser($shopUser); + $this->getShopUser()->shouldReturn($shopUser); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Messenger/Command/Vendor/UpdateProductListingSpec.php b/OpenMarketplace/spec/Component/Core/Api/Messenger/Command/Vendor/UpdateProductListingSpec.php new file mode 100644 index 0000000..a57269a --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Messenger/Command/Vendor/UpdateProductListingSpec.php @@ -0,0 +1,47 @@ +shouldHaveType(UpdateProductListing::class); + } + + public function it_has_product_draft( + Draft $productDraft + ): void { + $this->setProductDraft($productDraft); + $this->getProductDraft()->shouldReturn($productDraft); + } + + public function it_has_vendor( + VendorInterface $vendor + ): void { + $this->setVendor($vendor); + $this->getVendor()->shouldReturn($vendor); + } + + public function it_has_product_listing( + ListingInterface $productListing + ): void { + $this->setProductListing($productListing); + $this->getProductListing()->shouldReturn($productListing); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Messenger/Command/Vendor/UploadVendorImageSpec.php b/OpenMarketplace/spec/Component/Core/Api/Messenger/Command/Vendor/UploadVendorImageSpec.php new file mode 100644 index 0000000..2581df5 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Messenger/Command/Vendor/UploadVendorImageSpec.php @@ -0,0 +1,40 @@ +shouldHaveType(UploadVendorImage::class); + $this->shouldImplement(UploadVendorImageInterface::class); + } + + public function it_has_file(): void + { + $file = new UploadedFile(__FILE__, 'test'); + $this->setFile($file); + $this->getFile()->shouldReturn($file); + } + + public function it_has_owner(VendorInterface $vendor): void + { + $this->setOwner($vendor); + $this->getOwner()->shouldReturn($vendor); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Messenger/CommandHandler/Vendor/CreateProductListingHandlerSpec.php b/OpenMarketplace/spec/Component/Core/Api/Messenger/CommandHandler/Vendor/CreateProductListingHandlerSpec.php new file mode 100644 index 0000000..95dea0d --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Messenger/CommandHandler/Vendor/CreateProductListingHandlerSpec.php @@ -0,0 +1,59 @@ +beConstructedWith($productListingFromDraftFactory, $manager, $imageUploader); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(CreateProductListingHandler::class); + } + + public function it_creates_product_listing( + CreateProductListingInterface $createProductListing, + Draft $productDraft, + VendorInterface $vendor, + ListingPersisterInterface $productListingFromDraftFactory, + ListingInterface $productListing, + ObjectManager $manager + ): void { + $createProductListing->getProductDraft()->willReturn($productDraft); + $createProductListing->getVendor()->willReturn($vendor); + + $productDraft->getVendor()->willReturn($vendor); + + $productListingFromDraftFactory->createNewProductListing($productDraft, $vendor); + + $productDraft->getProductListing()->willReturn($productListing); + $manager->persist($productListing)->shouldBeCalled(); + + $this($createProductListing)->shouldReturn($productListing); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Messenger/CommandHandler/Vendor/RegisterVendorHandlerSpec.php b/OpenMarketplace/spec/Component/Core/Api/Messenger/CommandHandler/Vendor/RegisterVendorHandlerSpec.php new file mode 100644 index 0000000..93d4620 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Messenger/CommandHandler/Vendor/RegisterVendorHandlerSpec.php @@ -0,0 +1,93 @@ +beConstructedWith($vendorProvider, $manager); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(RegisterVendorHandler::class); + } + + public function it_creates_a_vendor_for_current_shop_user( + VendorProviderInterface $vendorProvider, + ObjectManager $manager, + VendorInterface $vendor, + ShopUserInterface $shopUser, + RegisterVendorInterface $command, + Address $vendorAddress + ): void { + $command->getCompanyName()->willReturn('companyName'); + $command->getTaxIdentifier()->willReturn('taxIdentifier'); + $command->getBankAccountNumber()->willReturn('iban'); + $command->getPhoneNumber()->willReturn('phoneNumber'); + $command->getDescription()->willReturn('description'); + $command->getVendorAddress()->willReturn($vendorAddress); + $command->getSlug()->willReturn('slug'); + $command->getShopUser()->willReturn($shopUser); + + $vendorProvider->provide($shopUser)->willReturn($vendor); + + $vendor->setCompanyName('companyName')->shouldBeCalled(); + $vendor->setTaxIdentifier('taxIdentifier')->shouldBeCalled(); + $vendor->setBankAccountNumber('iban')->shouldBeCalled(); + $vendor->setPhoneNumber('phoneNumber')->shouldBeCalled(); + $vendor->setDescription('description')->shouldBeCalled(); + $vendor->setVendorAddress($vendorAddress)->shouldBeCalled(); + $vendor->setSlug('slug')->shouldBeCalled(); + + $manager->persist($vendor)->shouldBeCalled(); + + $this($command)->shouldReturn($vendor); + } + + public function it_throws_an_exception_if_shop_user_is_not_set(): void + { + $command = new RegisterVendor('companyName', 'taxIdentifier', 'iban', 'phoneNumber', 'description', new Address()); + $command->setSlug('slug'); + + $this + ->shouldThrow(\DomainException::class) + ->during('__invoke', [$command]) + ; + } + + public function it_throws_an_exception_if_slug_is_not_set(): void + { + $command = new RegisterVendor('companyName', 'taxIdentifier', 'iban', 'phoneNumber', 'description', new Address()); + $shopUser = new ShopUser(); + $command->setShopUser($shopUser); + + $this + ->shouldThrow(\DomainException::class) + ->during('__invoke', [$command]) + ; + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Messenger/CommandHandler/Vendor/UpdateProductListingHandlerSpec.php b/OpenMarketplace/spec/Component/Core/Api/Messenger/CommandHandler/Vendor/UpdateProductListingHandlerSpec.php new file mode 100644 index 0000000..8677e29 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Messenger/CommandHandler/Vendor/UpdateProductListingHandlerSpec.php @@ -0,0 +1,71 @@ +beConstructedWith( + $listingPersister, + $productListingRepository + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(UpdateProductListingHandler::class); + } + + public function it_updates_product_listing( + UpdateProductListingInterface $updateProductListing, + Draft $productDraft, + Draft $previousProductDraft, + VendorInterface $vendor, + ListingInterface $modelProductListing, + ListingInterface $productListing, + ListingRepositoryInterface $productListingRepository, + ImageInterface $image + ): void { + $modelProductListing->getId()->willReturn(10); + + $updateProductListing->getProductDraft()->willReturn($productDraft); + $updateProductListing->getVendor()->willReturn($vendor); + $updateProductListing->getProductListing()->willReturn($modelProductListing); + $productListingRepository->find(10)->willReturn($productListing); + + $previousProductDraft->getVersionNumber()->willReturn(1); + $productListing->getLatestDraft()->willReturn($previousProductDraft); + + $previousProductDraft->getCode()->willReturn('code'); + $productDraft->setCode('code')->shouldBeCalled(); + $productDraft->setProductListing($productListing)->shouldBeCalled(); + + $images = new ArrayCollection([$image->getWrappedObject()]); + $productDraft->getImages()->willReturn($images); + + $this($updateProductListing)->shouldReturn($productListing); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Messenger/CommandHandler/Vendor/UploadVendorBackgroundImageHandlerSpec.php b/OpenMarketplace/spec/Component/Core/Api/Messenger/CommandHandler/Vendor/UploadVendorBackgroundImageHandlerSpec.php new file mode 100644 index 0000000..9a8cb1c --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Messenger/CommandHandler/Vendor/UploadVendorBackgroundImageHandlerSpec.php @@ -0,0 +1,124 @@ +beConstructedWith($vendorBackgroundImageFactory, $imageUploader, $manager, $vendorBackgroundImageRepository); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(UploadVendorBackgroundImageHandler::class); + } + + public function it_creates_vendor_background_image( + BackgroundImageFactoryInterface $vendorBackgroundImageFactory, + ImageUploaderInterface $imageUploader, + ObjectManager $manager, + UploadVendorBackgroundImageInterface $command, + VendorInterface $owner, + BackgroundImageInterface $vendorBackgroundImage + ): void { + $file = new UploadedFile(__FILE__, 'test'); + $command->getFile()->willReturn($file); + $command->getOwner()->willReturn($owner); + $owner->getBackgroundImage()->willReturn(null); + + $vendorBackgroundImageFactory->createNew()->willReturn($vendorBackgroundImage); + + $vendorBackgroundImage->setFile($file)->shouldBeCalled(); + $vendorBackgroundImage->setOwner($owner)->shouldBeCalled(); + $owner->setBackgroundImage($vendorBackgroundImage)->shouldBeCalled(); + $imageUploader->upload($vendorBackgroundImage)->shouldBeCalled(); + + $manager->persist(Argument::any())->shouldBeCalledTimes(2); + + $this($command)->shouldReturn($vendorBackgroundImage); + } + + public function it_removes_previous_background_image( + BackgroundImageFactoryInterface $vendorBackgroundImageFactory, + RepositoryInterface $vendorBackgroundImageRepository, + UploadVendorBackgroundImageInterface $command, + VendorInterface $owner, + BackgroundImageInterface $previousBackgroundImage, + BackgroundImageInterface $vendorBackgroundImage + ): void { + $file = new UploadedFile(__FILE__, 'test'); + $command->getFile()->willReturn($file); + $command->getOwner()->willReturn($owner); + $owner->getBackgroundImage()->willReturn($previousBackgroundImage); + + $vendorBackgroundImageFactory->createNew()->willReturn($vendorBackgroundImage); + + $vendorBackgroundImage->setFile($file)->shouldBeCalled(); + $vendorBackgroundImage->setOwner($owner)->shouldBeCalled(); + $owner->setBackgroundImage($vendorBackgroundImage)->shouldBeCalled(); + + $vendorBackgroundImageRepository->remove(Argument::any())->shouldBeCalled(); + + $this($command)->shouldReturn($vendorBackgroundImage); + } + + public function it_throws_exception_on_empty_file( + BackgroundImageFactoryInterface $vendorBackgroundImageFactory, + RepositoryInterface $vendorBackgroundImageRepository, + UploadVendorBackgroundImageInterface $command, + VendorInterface $owner, + BackgroundImageInterface $previousBackgroundImage, + BackgroundImageInterface $vendorBackgroundImage + ): void { + $command->getFile()->willReturn(null); + + $this + ->shouldThrow(\DomainException::class) + ->during('__invoke', [$command]) + ; + } + + public function it_throws_exception_on_empty_owner( + BackgroundImageFactoryInterface $vendorBackgroundImageFactory, + RepositoryInterface $vendorBackgroundImageRepository, + UploadVendorBackgroundImageInterface $command, + VendorInterface $owner, + BackgroundImageInterface $previousBackgroundImage, + BackgroundImageInterface $vendorBackgroundImage + ): void { + $file = new UploadedFile(__FILE__, 'test'); + $command->getFile()->willReturn($file); + $command->getOwner()->willReturn(null); + + $this + ->shouldThrow(\DomainException::class) + ->during('__invoke', [$command]) + ; + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Messenger/CommandHandler/Vendor/UploadVendorLogoImageHandlerSpec.php b/OpenMarketplace/spec/Component/Core/Api/Messenger/CommandHandler/Vendor/UploadVendorLogoImageHandlerSpec.php new file mode 100644 index 0000000..319e0bc --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Messenger/CommandHandler/Vendor/UploadVendorLogoImageHandlerSpec.php @@ -0,0 +1,124 @@ +beConstructedWith($vendorImageFactory, $imageUploader, $manager, $vendorImageRepository); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(UploadVendorLogoImageHandler::class); + } + + public function it_creates_vendor_image( + LogoImageFactoryInterface $vendorImageFactory, + ImageUploaderInterface $imageUploader, + ObjectManager $manager, + UploadVendorImageInterface $command, + VendorInterface $owner, + LogoImageInterface $vendorImage + ): void { + $file = new UploadedFile(__FILE__, 'test'); + $command->getFile()->willReturn($file); + $command->getOwner()->willReturn($owner); + $owner->getImage()->willReturn(null); + + $vendorImageFactory->createNew()->willReturn($vendorImage); + + $vendorImage->setFile($file)->shouldBeCalled(); + $vendorImage->setOwner($owner)->shouldBeCalled(); + $owner->setImage($vendorImage)->shouldBeCalled(); + $imageUploader->upload($vendorImage)->shouldBeCalled(); + + $manager->persist(Argument::any())->shouldBeCalledTimes(2); + + $this($command)->shouldReturn($vendorImage); + } + + public function it_removes_previous_image( + LogoImageFactoryInterface $vendorImageFactory, + RepositoryInterface $vendorImageRepository, + UploadVendorImageInterface $command, + VendorInterface $owner, + LogoImageInterface $previousImage, + LogoImageInterface $vendorImage + ): void { + $file = new UploadedFile(__FILE__, 'test'); + $command->getFile()->willReturn($file); + $command->getOwner()->willReturn($owner); + $owner->getImage()->willReturn($previousImage); + + $vendorImageFactory->createNew()->willReturn($vendorImage); + + $vendorImage->setFile($file)->shouldBeCalled(); + $vendorImage->setOwner($owner)->shouldBeCalled(); + $owner->setImage($vendorImage)->shouldBeCalled(); + + $vendorImageRepository->remove(Argument::any())->shouldBeCalled(); + + $this($command)->shouldReturn($vendorImage); + } + + public function it_throws_exception_on_empty_file( + LogoImageFactoryInterface $vendorImageFactory, + RepositoryInterface $vendorImageRepository, + UploadVendorImageInterface $command, + VendorInterface $owner, + LogoImageInterface $previousImage, + LogoImageInterface $vendorImage + ): void { + $command->getFile()->willReturn(null); + + $this + ->shouldThrow(\DomainException::class) + ->during('__invoke', [$command]) + ; + } + + public function it_throws_exception_on_empty_owner( + LogoImageFactoryInterface $vendorImageFactory, + RepositoryInterface $vendorImageRepository, + UploadVendorImageInterface $command, + VendorInterface $owner, + LogoImageInterface $previousImage, + LogoImageInterface $vendorImage + ): void { + $file = new UploadedFile(__FILE__, 'test'); + $command->getFile()->willReturn($file); + $command->getOwner()->willReturn(null); + + $this + ->shouldThrow(\DomainException::class) + ->during('__invoke', [$command]) + ; + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Provider/PathPrefixProviderSpec.php b/OpenMarketplace/spec/Component/Core/Api/Provider/PathPrefixProviderSpec.php new file mode 100644 index 0000000..1d85a83 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Provider/PathPrefixProviderSpec.php @@ -0,0 +1,90 @@ +beConstructedWith( + $pathPrefixProvider, + $vendorContext, + $sectionProvider, + 'api/v2/shop/account/vendor' + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(PathPrefixProvider::class); + $this->shouldHaveType(PathPrefixProviderInterface::class); + } + + public function it_return_vendor_prefix_if_vendor_path(): void + { + $this->getPathPrefix('api/v2/shop/account/vendor/something')->shouldReturn('vendor'); + } + + public function it_run_base_method_if_does_not_vendor_path( + PathPrefixProviderInterface $pathPrefixProvider, + ): void { + $pathPrefixProvider->getPathPrefix('api/v2/shop/account/something')->willReturn('base'); + + $this->getPathPrefix('api/v2/shop/account/something')->shouldReturn('base'); + } + + public function it_return_shop_vendor_prefix_if_currently_legged_in_is_vendor_and_shop_vendor_section( + VendorContextInterface $vendorContext, + VendorInterface $vendor, + SectionProviderInterface $sectionProvider, + ShopVendorApiSection $section + ): void { + $sectionProvider->getSection()->willReturn($section); + $vendorContext->getVendor()->willReturn($vendor); + + $this->getCurrentPrefix()->shouldReturn('shop_vendor'); + } + + public function it_run_base_method_if_currently_legged_in_is_not_vendor( + VendorContextInterface $vendorContext, + PathPrefixProviderInterface $pathPrefixProvider, + ): void { + $vendorContext->getVendor()->willReturn(null); + $pathPrefixProvider->getCurrentPrefix()->willReturn('base'); + + $this->getCurrentPrefix()->shouldReturn('base'); + } + + public function it_run_base_method_if_currently_legged_in_is_vendor_and_shop_section( + VendorContextInterface $vendorContext, + PathPrefixProviderInterface $pathPrefixProvider, + SectionProviderInterface $sectionProvider, + ShopApiSection $section + ): void { + $sectionProvider->getSection()->willReturn($section); + $vendorContext->getVendor()->willReturn(null); + $pathPrefixProvider->getCurrentPrefix()->willReturn('base'); + + $this->getCurrentPrefix()->shouldReturn('base'); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Provider/VendorProviderSpec.php b/OpenMarketplace/spec/Component/Core/Api/Provider/VendorProviderSpec.php new file mode 100644 index 0000000..0a207e3 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Provider/VendorProviderSpec.php @@ -0,0 +1,59 @@ +beConstructedWith($vendorFactory); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(VendorProvider::class); + $this->shouldImplement(VendorProviderInterface::class); + } + + public function it_create_new_vendor_when_shop_user_has_no_vendor_context( + ShopUserInterface $shopUser, + FactoryInterface $vendorFactory, + VendorInterface $vendor + ): void { + $shopUser->getVendor()->willReturn(null); + + $vendorFactory->createNew()->willReturn($vendor); + $vendor->setShopUser($shopUser)->shouldBeCalled(); + + $this->provide($shopUser) + ->shouldReturn($vendor); + } + + public function it_returns_vendor_from_shop_user_context( + ShopUserInterface $shopUser, + VendorInterface $vendor + ): void { + $shopUser->getVendor()->willReturn($vendor); + $vendor->setShopUser($shopUser)->shouldNotBeCalled(); + + $this->provide($shopUser) + ->shouldReturn($vendor); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/SectionResolver/ShopVendorApiUriBasedSectionResolverSpec.php b/OpenMarketplace/spec/Component/Core/Api/SectionResolver/ShopVendorApiUriBasedSectionResolverSpec.php new file mode 100644 index 0000000..1218a84 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/SectionResolver/ShopVendorApiUriBasedSectionResolverSpec.php @@ -0,0 +1,90 @@ +beConstructedWith('/api/v2/shop/account/vendor', $shopVendorApiSectionFactory); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(ShopVendorApiUriBasedSectionResolver::class); + $this->shouldHaveType(UriBasedSectionResolverInterface::class); + } + + public function it_returns_shop_vendor_section_if_path_starts_with_api_v2_shop_vendor( + ShopVendorApiSectionFactoryInterface $shopVendorApiSectionFactory, + ShopVendorApiSection $shopVendorApiSection, + ): void { + $shopVendorApiSectionFactory->createNew()->willReturn($shopVendorApiSection); + + $this->getSection('/api/v2/shop/account/vendor')->shouldReturn($shopVendorApiSection); + } + + public function it_returns_shop_vendor_section_if_path_starts_with_api_v2_shop_vendor_something( + ShopVendorApiSectionFactoryInterface $shopVendorApiSectionFactory, + ShopVendorApiSection $shopVendorApiSection, + ): void { + $shopVendorApiSectionFactory->createNew()->willReturn($shopVendorApiSection); + + $this->getSection('/api/v2/shop/account/vendor/something')->shouldReturn($shopVendorApiSection); + } + + public function it_throws_an_exception_if_path_starts_with_shop(): void + { + $this->shouldThrow(SectionCannotBeResolvedException::class)->during('getSection', ['/shop']); + } + + public function it_throws_an_exception_if_path_starts_with_admin(): void + { + $this->shouldThrow(SectionCannotBeResolvedException::class)->during('getSection', ['/admin']); + } + + public function it_throws_an_exception_if_path_starts_with_api(): void + { + $this->shouldThrow(SectionCannotBeResolvedException::class)->during('getSection', ['/en_US/api']); + } + + public function it_throws_an_exception_if_path_starts_with_api_v1(): void + { + $this->shouldThrow(SectionCannotBeResolvedException::class)->during('getSection', ['/api/v1']); + } + + public function it_throws_an_exception_if_path_starts_with_api_v2(): void + { + $this->shouldThrow(SectionCannotBeResolvedException::class)->during('getSection', ['/api/v1']); + } + + public function it_throws_an_exception_if_path_starts_with_api_v2_shop(): void + { + $this->shouldThrow(SectionCannotBeResolvedException::class)->during('getSection', ['/api/v2/shop']); + } + + public function it_throws_an_exception_if_path_starts_with_api_v2_admin(): void + { + $this->shouldThrow(SectionCannotBeResolvedException::class)->during('getSection', ['/api/v2/admin']); + } + + public function it_throws_an_exception_if_path_starts_with_api_v2_shop_vendors(): void + { + $this->shouldThrow(SectionCannotBeResolvedException::class)->during('getSection', ['/api/v2/shop/vendors']); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Security/Voter/TranslatableVendorAwareVoterSpec.php b/OpenMarketplace/spec/Component/Core/Api/Security/Voter/TranslatableVendorAwareVoterSpec.php new file mode 100644 index 0000000..40ac19b --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Security/Voter/TranslatableVendorAwareVoterSpec.php @@ -0,0 +1,138 @@ +beConstructedWith($vendorContext); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(TranslatableVendorAwareVoter::class); + } + + public function it_does_not_support_wrong_subject( + VendorContextInterface $vendorContext, + VendorInterface $vendor, + TokenInterface $token + ): void { + $vendorContext->getVendor()->shouldNotBeCalled(); + + $this->vote($token, $vendor, ['TRANSLATABLE_VENDOR_AWARE_OBJECT_UPDATE']); + } + + public function it_does_not_support_wrong_attribute( + VendorContextInterface $vendorContext, + TranslationInterface $translation, + VendorAwareInterface $vendorAware, + TokenInterface $token + ): void { + $vendorAware->implement(TranslatableInterface::class); + $translation->getTranslatable()->willReturn($vendorAware); + $vendorContext->getVendor()->shouldNotBeCalled(); + + $this->vote($token, $translation, ['WRONG_ATTRIBUTE']); + } + + public function it_supports_proper_subject_and_attribute( + VendorContextInterface $vendorContext, + TranslationInterface $translation, + VendorAwareInterface $vendorAware, + VendorInterface $vendor, + TokenInterface $token + ): void { + $vendorAware->implement(TranslatableInterface::class); + $vendorAware->getVendor()->willReturn($vendor); + + $translation->getTranslatable()->willReturn($vendorAware); + + $vendorContext->getVendor()->willReturn($vendor); + $vendorContext->getVendor()->shouldBeCalled(); + + $this->vote($token, $translation, ['TRANSLATABLE_VENDOR_AWARE_OBJECT_UPDATE']); + } + + public function it_denied_access_when_current_user_is_not_in_vendor_context( + VendorContextInterface $vendorContext, + TranslationInterface $translation, + VendorAwareInterface $vendorAware, + TokenInterface $token + ): void { + $vendorAware->implement(TranslatableInterface::class); + + $translation->getTranslatable()->willReturn($vendorAware); + $vendorContext->getVendor()->willReturn(null); + + $vendorContext->getVendor()->shouldBeCalled(); + $translation->getTranslatable()->shouldBeCalled(); + + $this->vote($token, $translation, ['TRANSLATABLE_VENDOR_AWARE_OBJECT_UPDATE'])->shouldReturn(Voter::ACCESS_DENIED); + } + + public function it_denied_access_when_current_user_is_in_wrong_vendor_context( + VendorContextInterface $vendorContext, + TranslationInterface $translation, + VendorAwareInterface $vendorAware, + VendorInterface $vendor, + VendorInterface $otherVendor, + TokenInterface $token + ): void { + $vendorAware->implement(TranslatableInterface::class); + + $vendor->getId()->willReturn(1); + $vendorAware->getVendor()->willReturn($vendor); + $translation->getTranslatable()->willReturn($vendorAware); + + $otherVendor->getId()->willReturn(2); + $vendorContext->getVendor()->willReturn($otherVendor); + + $vendorContext->getVendor()->shouldBeCalled(); + $translation->getTranslatable()->shouldBeCalled(); + + $this->vote($token, $translation, ['TRANSLATABLE_VENDOR_AWARE_OBJECT_UPDATE'])->shouldReturn(Voter::ACCESS_DENIED); + } + + public function it_grant_access_when_current_user_is_in_same_vendor_context( + VendorContextInterface $vendorContext, + TranslationInterface $translation, + VendorAwareInterface $vendorAware, + VendorInterface $vendor, + TokenInterface $token + ): void { + $vendorAware->implement(TranslatableInterface::class); + + $vendor->getId()->willReturn(1); + $vendorAware->getVendor()->willReturn($vendor); + $translation->getTranslatable()->willReturn($vendorAware); + + $vendorContext->getVendor()->willReturn($vendor); + + $vendorContext->getVendor()->shouldBeCalled(); + $translation->getTranslatable()->shouldBeCalled(); + + $this->vote($token, $translation, ['TRANSLATABLE_VENDOR_AWARE_OBJECT_UPDATE'])->shouldReturn(Voter::ACCESS_GRANTED); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Security/Voter/VendorAwareVoterSpec.php b/OpenMarketplace/spec/Component/Core/Api/Security/Voter/VendorAwareVoterSpec.php new file mode 100644 index 0000000..393e074 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Security/Voter/VendorAwareVoterSpec.php @@ -0,0 +1,98 @@ +beConstructedWith($vendorContext); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(VendorAwareVoter::class); + } + + public function it_does_not_support_wrong_subject( + VendorContextInterface $vendorContext, + VendorInterface $vendor, + TokenInterface $token + ): void { + $vendorContext->getVendor()->shouldNotBeCalled(); + + $this->vote($token, $vendor, ['VENDOR_AWARE_OBJECT_CREATE']); + } + + public function it_does_not_support_wrong_attribute( + VendorContextInterface $vendorContext, + VendorAwareInterface $vendorAware, + TokenInterface $token + ): void { + $vendorContext->getVendor()->shouldNotBeCalled(); + + $this->vote($token, $vendorAware, ['WRONG_ATTRIBUTE']); + } + + public function it_supports_proper_subject_and_attribute( + VendorContextInterface $vendorContext, + VendorAwareInterface $vendorAware, + TokenInterface $token + ): void { + $vendorContext->getVendor()->shouldBeCalled(); + + $this->vote($token, $vendorAware, ['VENDOR_AWARE_OBJECT_CREATE']); + } + + public function it_returns_access_denied_when_current_user_is_not_in_vendor_context( + VendorContextInterface $vendorContext, + VendorAwareInterface $vendorAware, + TokenInterface $token + ): void { + $vendorContext->getVendor()->willReturn(null); + $vendorContext->getVendor()->shouldBeCalled(); + + $this->vote($token, $vendorAware, ['VENDOR_AWARE_OBJECT_CREATE'])->shouldReturn(Voter::ACCESS_DENIED); + } + + public function it_denied_access_when_current_user_is_not_in_vendor_context( + VendorContextInterface $vendorContext, + VendorAwareInterface $vendorAware, + TokenInterface $token + ): void { + $vendorContext->getVendor()->willReturn(null); + $vendorContext->getVendor()->shouldBeCalled(); + + $this->vote($token, $vendorAware, ['VENDOR_AWARE_OBJECT_CREATE'])->shouldReturn(Voter::ACCESS_DENIED); + } + + public function it_grant_access_when_current_user_is_in_vendor_context( + VendorContextInterface $vendorContext, + VendorAwareInterface $vendorAware, + VendorInterface $vendor, + TokenInterface $token + ): void { + $vendorContext->getVendor()->willReturn($vendor); + $vendorContext->getVendor()->shouldBeCalled(); + + $this->vote($token, $vendorAware, ['VENDOR_AWARE_OBJECT_CREATE'])->shouldReturn(Voter::ACCESS_GRANTED); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Security/Voter/VendorLogoImageVoterSpec.php b/OpenMarketplace/spec/Component/Core/Api/Security/Voter/VendorLogoImageVoterSpec.php new file mode 100644 index 0000000..736023a --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Security/Voter/VendorLogoImageVoterSpec.php @@ -0,0 +1,117 @@ +beConstructedWith($userContext); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(VendorLogoImageVoter::class); + } + + public function it_grants_access_when_current_vendor_is_image_owner_during_delete_action( + UserContextInterface $userContext, + ShopUserInterface $user, + VendorInterface $vendor, + LogoImageInterface $vendorImage, + TokenInterface $token + ): void { + $user->getVendor()->willReturn($vendor); + $userContext->getUser()->willReturn($user); + $vendor->getId()->willReturn(1); + $vendorImage->getOwner()->willReturn($vendor); + + $this->vote($token, $vendorImage, [VendorLogoImageVoter::DELETE]) + ->shouldReturn(VoterInterface::ACCESS_GRANTED); + } + + public function it_denies_access_when_current_vendor_is_not_image_owner_during_delete_action( + UserContextInterface $userContext, + ShopUserInterface $user, + VendorInterface $vendor, + VendorInterface $imageOwner, + LogoImageInterface $vendorImage, + TokenInterface $token + ): void { + $user->getVendor()->willReturn($vendor); + $userContext->getUser()->willReturn($user); + $vendor->getId()->willReturn(1); + $imageOwner->getId()->willReturn(2); + $vendorImage->getOwner()->willReturn($imageOwner); + + $this->vote($token, $vendorImage, [VendorLogoImageVoter::DELETE]) + ->shouldReturn(VoterInterface::ACCESS_DENIED); + } + + public function it_denies_access_when_current_user_is_not_in_vendor_context_during_delete_action( + UserContextInterface $userContext, + ShopUserInterface $user, + VendorInterface $vendor, + LogoImageInterface $vendorImage, + TokenInterface $token + ): void { + $user->getVendor()->willReturn(null); + $userContext->getUser()->willReturn($user); + $vendor->getId()->willReturn(1); + $vendorImage->getOwner()->willReturn($vendor); + + $this->vote($token, $vendorImage, [VendorLogoImageVoter::DELETE]) + ->shouldReturn(VoterInterface::ACCESS_DENIED); + } + + public function it_abstains_when_there_is_different_action( + UserContextInterface $userContext, + ShopUserInterface $user, + VendorInterface $vendor, + LogoImageInterface $vendorImage, + TokenInterface $token + ): void { + $user->getVendor()->willReturn($vendor); + $userContext->getUser()->willReturn($user); + $vendor->getId()->willReturn(1); + $vendorImage->getOwner()->willReturn($vendor); + + $this->vote($token, $vendorImage, ['OTHER_ACTION']) + ->shouldReturn(VoterInterface::ACCESS_ABSTAIN); + } + + public function it_abstains_when_subject_is_not_vendor_image( + UserContextInterface $userContext, + ShopUserInterface $user, + VendorInterface $vendor, + LogoImageInterface $vendorImage, + TokenInterface $token + ): void { + $user->getVendor()->willReturn($vendor); + $userContext->getUser()->willReturn($user); + $vendor->getId()->willReturn(1); + $vendorImage->getOwner()->willReturn($vendor); + + $this->vote($token, $vendor, [VendorLogoImageVoter::DELETE]) + ->shouldReturn(VoterInterface::ACCESS_ABSTAIN); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Serializer/ProductVariantNormalizerSpec.php b/OpenMarketplace/spec/Component/Core/Api/Serializer/ProductVariantNormalizerSpec.php new file mode 100644 index 0000000..64aa5b6 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Serializer/ProductVariantNormalizerSpec.php @@ -0,0 +1,79 @@ +beConstructedWith($productVariantNormalizer, $sectionProvider); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(ProductVariantNormalizer::class); + $this->shouldHaveType(ContextAwareNormalizerInterface::class); + $this->shouldHaveType(NormalizerAwareInterface::class); + } + + public function it_normalize_by_inner( + ContextAwareNormalizerInterface $productVariantNormalizer, + ProductVariantInterface $productVariant, + ): void { + $productVariantNormalizer->normalize($productVariant, null, [])->willReturn($productVariant); + + $this->normalize($productVariant)->shouldReturn($productVariant); + } + + public function it_does_not_supports_normalization_if_inner_not( + ContextAwareNormalizerInterface $productVariantNormalizer, + ProductVariantInterface $productVariant, + ): void { + $productVariantNormalizer->supportsNormalization($productVariant, null, [])->willReturn(false); + + $this->supportsNormalization($productVariant)->shouldReturn(false); + } + + public function it_does_not_supports_normalization_if_section_is_shop_vendor_api( + ContextAwareNormalizerInterface $productVariantNormalizer, + ProductVariantInterface $productVariant, + SectionProviderInterface $sectionProvider, + ShopVendorApiSection $shopVendorApiSection, + ): void { + $productVariantNormalizer->supportsNormalization($productVariant, null, [])->willReturn(true); + $sectionProvider->getSection()->willReturn($shopVendorApiSection); + + $this->supportsNormalization($productVariant)->shouldReturn(false); + } + + public function it_supports_normalization_if_section_is_not_shop_vendor_api( + ContextAwareNormalizerInterface $productVariantNormalizer, + ProductVariantInterface $productVariant, + SectionProviderInterface $sectionProvider, + ShopApiSection $shopApiSection, + ): void { + $productVariantNormalizer->supportsNormalization($productVariant, null, [])->shouldBeCalled()->willReturn(true); + $sectionProvider->getSection()->willReturn($shopApiSection); + + $this->supportsNormalization($productVariant)->shouldReturn(true); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Api/Validator/UniqueShopUserVendorValidatorSpec.php b/OpenMarketplace/spec/Component/Core/Api/Validator/UniqueShopUserVendorValidatorSpec.php new file mode 100644 index 0000000..6b1a6f3 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Api/Validator/UniqueShopUserVendorValidatorSpec.php @@ -0,0 +1,104 @@ +beConstructedWith($userContext); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(UniqueShopUserVendorValidator::class); + $this->shouldImplement(ConstraintValidatorInterface::class); + } + + public function it_throws_an_exception_on_wrong_constraint( + Constraint $constraint + ): void { + $this + ->shouldThrow(\InvalidArgumentException::class) + ->during('validate', ['', $constraint]) + ; + } + + public function it_throws_an_exception_current_user_is_not_shop_user( + UserContextInterface $userContext, + UserInterface $user + ): void { + $constraint = new UniqueShopUserVendor(); + + $userContext->getUser()->willReturn($user); + + $this + ->shouldThrow(\InvalidArgumentException::class) + ->during('validate', ['', $constraint]) + ; + } + + public function it_adds_violation_if_shop_user_has_vendor_context( + UserContextInterface $userContext, + ShopUserInterface $shopUser, + VendorInterface $vendor, + ExecutionContextInterface $executionContext + ): void { + $constraint = new UniqueShopUserVendor(); + + $this->initialize($executionContext); + + $shopUser->getVendor()->willReturn($vendor); + $userContext->getUser()->willReturn($shopUser); + + $executionContext + ->addViolation( + $constraint->message + ) + ->shouldBeCalled() + ; + + $this->validate('', $constraint); + } + + public function it_does_nothing_if_shop_user_has_not_vendor_context( + UserContextInterface $userContext, + ShopUserInterface $shopUser, + ExecutionContextInterface $executionContext + ): void { + $constraint = new UniqueShopUserVendor(); + + $this->initialize($executionContext); + + $userContext->getUser()->willReturn($shopUser); + + $executionContext + ->addViolation( + $constraint->message + ) + ->shouldNotBeCalled() + ; + + $this->validate('', $constraint); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Common/Resolver/CurrentUserResolverSpec.php b/OpenMarketplace/spec/Component/Core/Common/Resolver/CurrentUserResolverSpec.php new file mode 100644 index 0000000..e08f180 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Common/Resolver/CurrentUserResolverSpec.php @@ -0,0 +1,63 @@ +beConstructedWith($tokenStorage); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(CurrentUserResolver::class); + $this->shouldImplement(CurrentUserResolverInterface::class); + } + + public function it_returns_current_user( + TokenStorageInterface $tokenStorage, + UserInterface $user, + TokenInterface $token + ): void { + $tokenStorage->getToken() + ->willReturn($token); + + $token->getUser() + ->willReturn($user); + + $this->resolve() + ->shouldReturn($user); + } + + public function it_returns_null_when_didnt_find_current_user( + TokenStorageInterface $tokenStorage, + TokenInterface $token + ): void { + $tokenStorage->getToken() + ->willReturn($token); + + $token->getUser() + ->willReturn(null); + + $this->resolve() + ->shouldReturn(null); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Common/StateMachine/ProductDraftStateMachineTransitionSpec.php b/OpenMarketplace/spec/Component/Core/Common/StateMachine/ProductDraftStateMachineTransitionSpec.php new file mode 100644 index 0000000..8e0b222 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Common/StateMachine/ProductDraftStateMachineTransitionSpec.php @@ -0,0 +1,94 @@ +beConstructedWith( + $productDraftStateMachineFactory + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(ProductDraftStateMachineTransition::class); + } + + public function it_should_implement_interface(): void + { + $this->shouldImplement(ProductDraftStateMachineTransitionInterface::class); + } + + public function it_applies_transition( + DraftInterface $productDraft, + FactoryInterface $productDraftStateMachineFactory, + StateMachineInterface $stateMachine + ): void { + $productDraftStateMachineFactory->get( + $productDraft, + DraftTransitions::GRAPH + )->willReturn($stateMachine); + + $stateMachine->can(DraftTransitions::TRANSITION_ACCEPT) + ->willReturn(true); + + $stateMachine->apply(DraftTransitions::TRANSITION_ACCEPT) + ->willReturn(true); + + $productDraftStateMachineFactory->get($productDraft, DraftTransitions::GRAPH) + ->shouldBeCalled(); + + $stateMachine->can(DraftTransitions::TRANSITION_ACCEPT) + ->shouldBeCalled(); + + $stateMachine->apply(DraftTransitions::TRANSITION_ACCEPT) + ->shouldBeCalled(); + + $this->applyIfCan($productDraft, DraftTransitions::TRANSITION_ACCEPT); + } + + public function it_cannot_apply_transition( + DraftInterface $productDraft, + FactoryInterface $productDraftStateMachineFactory, + StateMachineInterface $stateMachine + ): void { + $productDraftStateMachineFactory->get( + $productDraft, + DraftTransitions::GRAPH + )->willReturn($stateMachine); + + $stateMachine->can(DraftTransitions::TRANSITION_ACCEPT) + ->willReturn(false); + + $productDraftStateMachineFactory->get($productDraft, DraftTransitions::GRAPH) + ->shouldBeCalled(); + + $stateMachine->can(DraftTransitions::TRANSITION_ACCEPT) + ->shouldBeCalled(); + + $stateMachine->apply(DraftTransitions::TRANSITION_ACCEPT) + ->shouldNotBeCalled(); + + $this->applyIfCan($productDraft, DraftTransitions::TRANSITION_ACCEPT); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Common/StateMachine/SettlementCallbacksSpec.php b/OpenMarketplace/spec/Component/Core/Common/StateMachine/SettlementCallbacksSpec.php new file mode 100644 index 0000000..605d643 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Common/StateMachine/SettlementCallbacksSpec.php @@ -0,0 +1,58 @@ +beConstructedWith( + $settlementStateMachineTransition, + $entityManager, + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(SettlementCallbacks::class); + } + + public function it_should_implement_interface(): void + { + $this->shouldImplement(SettlementCallbacksInterface::class); + } + + public function it_should_apply_payout_transaction( + SettlementStateMachineTransitionInterface $settlementStateMachineTransition, + EntityManagerInterface $entityManager, + SettlementInterface $settlement + ): void { + $settlementStateMachineTransition->applyIfCan( + $settlement, + SettlementTransitions::SETTLE, + )->shouldBeCalled(); + + $entityManager->flush()->shouldBeCalled(); + + $this->payout($settlement); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Common/StateMachine/SettlementStateMachineTransitionSpec.php b/OpenMarketplace/spec/Component/Core/Common/StateMachine/SettlementStateMachineTransitionSpec.php new file mode 100644 index 0000000..10f9d86 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Common/StateMachine/SettlementStateMachineTransitionSpec.php @@ -0,0 +1,105 @@ +beConstructedWith( + $settlementStateMachineFactory, + $entityManager, + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(SettlementStateMachineTransition::class); + } + + public function it_should_implement_interface(): void + { + $this->shouldImplement(SettlementStateMachineTransitionInterface::class); + } + + public function it_applies_transition( + SettlementInterface $settlement, + FactoryInterface $settlementStateMachineFactory, + EntityManagerInterface $entityManager, + StateMachineInterface $stateMachine, + ): void { + $settlementStateMachineFactory->get( + $settlement, + SettlementTransitions::GRAPH + )->willReturn($stateMachine); + + $stateMachine->can(SettlementTransitions::ACCEPT) + ->willReturn(true); + + $stateMachine->apply(SettlementTransitions::ACCEPT) + ->willReturn(true); + + $stateMachine->can(SettlementTransitions::ACCEPT) + ->shouldBeCalled(); + + $stateMachine->apply(SettlementTransitions::ACCEPT) + ->shouldBeCalled(); + + $settlementStateMachineFactory->get($settlement, SettlementTransitions::GRAPH) + ->shouldBeCalled(); + + $entityManager->persist($settlement) + ->shouldBeCalled(); + + $this->applyIfCan($settlement, SettlementTransitions::ACCEPT); + } + + public function it_cannot_apply_transition( + SettlementInterface $settlement, + FactoryInterface $settlementStateMachineFactory, + EntityManagerInterface $entityManager, + StateMachineInterface $stateMachine, + ): void { + $settlementStateMachineFactory->get( + $settlement, + SettlementTransitions::GRAPH + )->willReturn($stateMachine); + + $stateMachine->can(SettlementTransitions::SETTLE) + ->willReturn(false); + + $settlementStateMachineFactory->get($settlement, SettlementTransitions::GRAPH) + ->shouldBeCalled(); + + $stateMachine->can(SettlementTransitions::SETTLE) + ->shouldBeCalled(); + + $stateMachine->apply(SettlementTransitions::SETTLE) + ->shouldNotBeCalled(); + + $entityManager->persist($settlement) + ->shouldNotBeCalled(); + + $this->applyIfCan($settlement, SettlementTransitions::SETTLE); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Vendor/Security/Voter/OrderOperationVoterSpec.php b/OpenMarketplace/spec/Component/Core/Vendor/Security/Voter/OrderOperationVoterSpec.php new file mode 100644 index 0000000..0f7753a --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Vendor/Security/Voter/OrderOperationVoterSpec.php @@ -0,0 +1,109 @@ +beConstructedWith($stateMachineFactory); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(OrderOperationVoter::class); + $this->shouldHaveType(Voter::class); + } + + public function it_support_expected_attribute(): void + { + $this->supportsAttribute('VENDOR_ORDER_CANCEL')->shouldReturn(true); + } + + public function it_does_not_support_unexpected_attribute(): void + { + $this->supportsAttribute('WRONG_ATTRIBUTE')->shouldReturn(false); + } + + public function it_support_expected_type(): void + { + $this->supportsType(OrderInterface::class)->shouldReturn(true); + } + + public function it_does_not_support_unexpected_type(): void + { + $this->supportsType(OrderItemInterface::class)->shouldReturn(false); + } + + public function it_abstains_if_does_not_support_attribute( + TokenInterface $token, + OrderInterface $order, + ): void { + $this->vote($token, $order, ['WRONG_ATTRIBUTE'])->shouldReturn(VoterInterface::ACCESS_ABSTAIN); + } + + public function it_abstains_if_does_not_support_subject( + TokenInterface $token, + OrderItemInterface $orderItem, + ): void { + $this->vote($token, $orderItem, ['VENDOR_ORDER_CANCEL'])->shouldReturn(VoterInterface::ACCESS_ABSTAIN); + } + + public function it_denied_if_cannot_cancel_order( + TokenInterface $token, + OrderInterface $order, + FactoryInterface $stateMachineFactory, + StateMachineInterface $stateMachine, + ): void { + $stateMachineFactory->get($order, OrderTransitions::GRAPH)->willReturn($stateMachine); + $stateMachine->can(OrderTransitions::TRANSITION_CANCEL)->willReturn(false); + + $this->vote($token, $order, ['VENDOR_ORDER_CANCEL'])->shouldReturn(VoterInterface::ACCESS_DENIED); + } + + public function it_denied_if_order_not_paid( + TokenInterface $token, + OrderInterface $order, + FactoryInterface $stateMachineFactory, + StateMachineInterface $stateMachine, + ): void { + $stateMachineFactory->get($order, OrderTransitions::GRAPH)->willReturn($stateMachine); + $stateMachine->can(OrderTransitions::TRANSITION_CANCEL)->willReturn(true); + $order->getPaymentState()->willReturn(OrderPaymentStates::STATE_AWAITING_PAYMENT); + + $this->vote($token, $order, ['VENDOR_ORDER_CANCEL'])->shouldReturn(VoterInterface::ACCESS_DENIED); + } + + public function it_granted( + TokenInterface $token, + OrderInterface $order, + FactoryInterface $stateMachineFactory, + StateMachineInterface $stateMachine, + ): void { + $stateMachineFactory->get($order, OrderTransitions::GRAPH)->willReturn($stateMachine); + $stateMachine->can(OrderTransitions::TRANSITION_CANCEL)->willReturn(true); + $order->getPaymentState()->willReturn(OrderPaymentStates::STATE_PAID); + + $this->vote($token, $order, ['VENDOR_ORDER_CANCEL'])->shouldReturn(VoterInterface::ACCESS_GRANTED); + } +} diff --git a/OpenMarketplace/spec/Component/Core/Vendor/Twig/Extension/VendorClientExtensionSpec.php b/OpenMarketplace/spec/Component/Core/Vendor/Twig/Extension/VendorClientExtensionSpec.php new file mode 100644 index 0000000..f9bb9d5 --- /dev/null +++ b/OpenMarketplace/spec/Component/Core/Vendor/Twig/Extension/VendorClientExtensionSpec.php @@ -0,0 +1,56 @@ +beConstructedWith($customerRepository); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(VendorClientExtension::class); + $this->shouldHaveType(AbstractExtension::class); + } + + public function it_is_false_if_vendor_does_not_have_client( + CustomerRepositoryInterface $customerRepository, + VendorInterface $vendor, + CustomerInterface $customer + ): void { + $id = 1; + $customer->getId()->willReturn($id); + $customerRepository->findCustomerForVendor($vendor, '1')->willReturn(null); + + $this->isVendorClient($vendor, $customer)->shouldReturn(false); + } + + public function it_is_true_if_vendor_have_client( + CustomerRepositoryInterface $customerRepository, + VendorInterface $vendor, + CustomerInterface $customer + ): void { + $id = 1; + $customer->getId()->willReturn($id); + $customerRepository->findCustomerForVendor($vendor, '1')->willReturn($customer); + + $this->isVendorClient($vendor, $customer)->shouldReturn(true); + } +} diff --git a/OpenMarketplace/spec/Component/Messaging/Factory/MessageFactorySpec.php b/OpenMarketplace/spec/Component/Messaging/Factory/MessageFactorySpec.php new file mode 100644 index 0000000..f24935d --- /dev/null +++ b/OpenMarketplace/spec/Component/Messaging/Factory/MessageFactorySpec.php @@ -0,0 +1,53 @@ +beConstructedWith($conversationMessageFactory); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(MessageFactory::class); + $this->shouldImplement(MessageFactoryInterface::class); + } + + public function it_create_new_message( + FactoryInterface $conversationMessageFactory, + MessageInterface $message + ): void { + $conversationMessageFactory->createNew()->willReturn($message); + + $this->createNew()->shouldReturn($message); + } + + public function it_create_new_with_archive_request( + FactoryInterface $conversationMessageFactory, + MessageInterface $message + ): void { + $conversationMessageFactory->createNew()->willReturn($message); + $message->setContent(MessagesStorage::ARCHIVE_REQUEST_MESSAGE)->shouldBeCalled(); + + $this->createNewWithArchiveRequest() + ->shouldReturn($message); + } +} diff --git a/OpenMarketplace/spec/Component/Messaging/MessagePersisterSpec.php b/OpenMarketplace/spec/Component/Messaging/MessagePersisterSpec.php new file mode 100644 index 0000000..4a58db6 --- /dev/null +++ b/OpenMarketplace/spec/Component/Messaging/MessagePersisterSpec.php @@ -0,0 +1,158 @@ +beConstructedWith($actualUserResolver, $fileUploader, $conversationRepository); + } + + public function it_is_initializable() + { + $this->shouldHaveType(MessagePersister::class); + $this->shouldImplement(MessagePersisterInterface::class); + } + + public function it_processes_message_and_adds_it_to_given_conversation( + CurrentUserResolverInterface $actualUserResolver, + AttachmentUploaderInterface $fileUploader, + ConversationRepositoryInterface $conversationRepository, + UserInterface $user, + MessageInterface $message, + ConversationInterface $conversation + ): void { + $file = new UploadedFile('spec/testfiles/test.txt', 'test.txt'); + $filename = 'filename'; + $messageContent = 'messageContent'; + $actualUserResolver->resolve()->willReturn($user); + $conversationRepository->find(1)->willReturn($conversation); + $fileUploader->upload($file)->willReturn($filename); + $message->setFilename($filename)->shouldBeCalled(); + $message->getContent()->willReturn($messageContent); + $message->setContent(strip_tags($messageContent))->shouldBeCalled(); + + $message->setAuthor($user)->shouldBeCalled(); + + $conversation->addMessage($message)->shouldBeCalled(); + + $conversationRepository->add($conversation)->shouldBeCalled(); + + $this->createWithConversation(1, $message, $file, true); + } + + public function it_processes_message_admin_create_not_send_file( + CurrentUserResolverInterface $actualUserResolver, + AttachmentUploaderInterface $fileUploader, + ConversationRepositoryInterface $conversationRepository, + AdminUserInterface $admin, + MessageInterface $message, + ConversationInterface $conversation + ): void { + $messageContent = 'messageContent'; + $actualUserResolver->resolve()->willReturn($admin); + $conversationRepository->find(1)->willReturn($conversation); + $message->getContent()->willReturn($messageContent); + $message->setContent(strip_tags($messageContent))->shouldBeCalled(); + + $message->setAuthor($admin)->shouldBeCalled(); + + $conversation->addMessage($message)->shouldBeCalled(); + + $conversationRepository->add($conversation)->shouldBeCalled(); + + $this->createWithConversation(1, $message, null, true); + } + + public function it_throws_exception_if_user_is_not_found( + CurrentUserResolverInterface $actualUserResolver, + MessageInterface $message + ): void { + $actualUserResolver->resolve()->willReturn(null); + + $this->shouldThrow(UserNotFoundException::class) + ->during('createWithConversation', [ + 1, + $message, + ]); + } + + public function it_doesnt_strip_tags_on_false_parameter( + CurrentUserResolverInterface $actualUserResolver, + AttachmentUploaderInterface $fileUploader, + ConversationRepositoryInterface $conversationRepository, + AdminUserInterface $admin, + UserInterface $user, + MessageInterface $message, + ConversationInterface $conversation + ): void { + $messageContent = 'messageContent'; + $actualUserResolver->resolve()->willReturn($admin); + $conversationRepository->find(1)->willReturn($conversation); + $message->getContent()->willReturn($messageContent); + $message->setContent(strip_tags($messageContent))->shouldNotBeCalled(); + + $message->setAuthor($admin)->shouldBeCalled(); + + $conversation->addMessage($message)->shouldBeCalled(); + + $conversationRepository->add($conversation)->shouldBeCalled(); + + $this->createWithConversation(1, $message, null, false); + } + + public function it_adds_file( + CurrentUserResolverInterface $actualUserResolver, + AttachmentUploaderInterface $fileUploader, + ConversationRepositoryInterface $conversationRepository, + UserInterface $user, + MessageInterface $message, + ConversationInterface $conversation + ): void { + $file = new UploadedFile('spec/testfiles/test.txt', 'test.txt'); + $filename = 'filename'; + $messageContent = 'messageContent'; + $actualUserResolver->resolve()->willReturn($user); + $conversationRepository->find(1)->willReturn($conversation); + + $fileUploader->upload($file)->willReturn($filename); + $message->setFilename($filename)->shouldBeCalled(); + + $message->getContent()->willReturn($messageContent); + $message->setContent(strip_tags($messageContent))->shouldBeCalled(); + + $message->setAuthor($user)->shouldBeCalled(); + + $conversation->addMessage($message)->shouldBeCalled(); + + $conversationRepository->add($conversation)->shouldBeCalled(); + + $this->createWithConversation(1, $message, $file, true); + } +} diff --git a/OpenMarketplace/spec/Component/Messaging/Validator/MessageFileMimeTypeValidatorSpec.php b/OpenMarketplace/spec/Component/Messaging/Validator/MessageFileMimeTypeValidatorSpec.php new file mode 100644 index 0000000..f1eee30 --- /dev/null +++ b/OpenMarketplace/spec/Component/Messaging/Validator/MessageFileMimeTypeValidatorSpec.php @@ -0,0 +1,97 @@ +beConstructedWith(['text/html', 'application/javascript']); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(MessageFileMimeTypeValidator::class); + $this->shouldImplement(ConstraintValidatorInterface::class); + } + + public function it_throws_an_exception_on_wrong_constraint( + Constraint $constraint, + MessageInterface $message + ): void { + $this + ->shouldThrow(UnexpectedTypeException::class) + ->during('validate', [$message, $constraint]); + } + + public function it_do_nothing_if_value_null( + ExecutionContextInterface $executionContext, + ): void { + $constraint = new MessageFileMimeTypeConstraint(); + + $this->initialize($executionContext); + + $this->validate(null, $constraint); + + $executionContext->addViolation($constraint->message)->shouldNotBeCalled(); + } + + public function it_do_nothing_if_value_empty( + ExecutionContextInterface $executionContext, + ): void { + $constraint = new MessageFileMimeTypeConstraint(); + + $this->initialize($executionContext); + + $this->validate('', $constraint); + + $executionContext->addViolation($constraint->message)->shouldNotBeCalled(); + } + + public function it_does_not_add_violation_if_file_has_different_type( + ExecutionContextInterface $executionContext + ): void { + $constraint = new MessageFileMimeTypeConstraint(); + $file = new File(__FILE__); + + $this->initialize($executionContext); + + $this->validate($file, $constraint); + + $executionContext->addViolation($constraint->message)->shouldNotHaveBeenCalled(); + } + + public function it_adds_validation_if_file_has_not_allowed_type( + ExecutionContextInterface $executionContext, + ConstraintViolationBuilderInterface $constraintViolationBuilder + ): void { + $constraint = new MessageFileMimeTypeConstraint(); + $this->beConstructedWith(['text/x-php']); + $file = new File(__FILE__); + + $this->initialize($executionContext); + + $this->validate($file, $constraint); + + $executionContext->addViolation($constraint->message, ['{{ type }}' => '"text/x-php"'])->shouldHaveBeenCalledOnce(); + } +} diff --git a/OpenMarketplace/spec/Component/Order/Calculator/ShipmentUnitsRecalculatorSpec.php b/OpenMarketplace/spec/Component/Order/Calculator/ShipmentUnitsRecalculatorSpec.php new file mode 100644 index 0000000..3ede0b0 --- /dev/null +++ b/OpenMarketplace/spec/Component/Order/Calculator/ShipmentUnitsRecalculatorSpec.php @@ -0,0 +1,94 @@ +shouldHaveType(ShipmentUnitsRecalculator::class); + $this->shouldImplement(ShipmentUnitsRecalculatorInterface::class); + } + + public function it_removes_units_from_shipments( + OrderInterface $order, + ShipmentInterface $shipment, + OrderItemUnitInterface $unit + ): void { + $order->getShipments()->willReturn(new ArrayCollection([$shipment->getWrappedObject()])); + $shipment->getUnits()->willReturn(new ArrayCollection([$unit->getWrappedObject()])); + $shipment->removeUnit($unit)->shouldBeCalled(); + $order->getItemUnits()->willReturn(new ArrayCollection()); + + $this->recalculateShipmentUnits($order); + } + + public function it_removes_units_from_shipments_and_adds_them_back_with_vendor( + OrderInterface $order, + ShipmentInterface $shipment, + OrderItemUnitInterface $unit, + OrderItemInterface $orderItem, + ProductVariantInterface $variant, + ProductInterface $product, + VendorInterface $vendor + ): void { + $order->getShipments()->willReturn(new ArrayCollection([$shipment->getWrappedObject()])); + $shipment->getUnits()->willReturn(new ArrayCollection([$unit->getWrappedObject()])); + $shipment->removeUnit($unit)->shouldBeCalled(); + $order->getItemUnits()->willReturn(new ArrayCollection([$unit->getWrappedObject()])); + $unit->getOrderItem()->willReturn($orderItem); + $orderItem->getVariant()->willReturn($variant); + $variant->getProduct()->willReturn($product); + $unit->getShipment()->willReturn(null); + $product->getVendor()->willReturn($vendor); + $order->getShipmentByVendor($vendor)->willReturn($shipment); + $shipment->addUnit($unit)->shouldBeCalled(); + + $this->recalculateShipmentUnits($order); + } + + public function it_removes_units_from_shipments_and_adds_them_back_without_vendor( + OrderInterface $order, + ShipmentInterface $shipment, + OrderItemUnitInterface $unit, + OrderItemInterface $orderItem, + ProductVariantInterface $variant, + ProductInterface $product, + VendorInterface $vendor, + ): void { + $order->getShipments()->willReturn(new ArrayCollection([$shipment->getWrappedObject()])); + $shipment->getUnits()->willReturn(new ArrayCollection([$unit->getWrappedObject()])); + $shipment->removeUnit($unit)->shouldBeCalled(); + $order->getItemUnits()->willReturn(new ArrayCollection([$unit->getWrappedObject()])); + $unit->getOrderItem()->willReturn($orderItem); + $orderItem->getVariant()->willReturn($variant); + $variant->getProduct()->willReturn($product); + $unit->getShipment()->willReturn(null); + $product->getVendor()->willReturn($vendor); + $order->getShipmentByVendor($vendor)->willReturn($shipment); + $shipment->addUnit($unit)->shouldBeCalled(); + + $this->recalculateShipmentUnits($order); + } +} diff --git a/OpenMarketplace/spec/Component/Order/Cloner/AddressClonerSpec.php b/OpenMarketplace/spec/Component/Order/Cloner/AddressClonerSpec.php new file mode 100644 index 0000000..8145f61 --- /dev/null +++ b/OpenMarketplace/spec/Component/Order/Cloner/AddressClonerSpec.php @@ -0,0 +1,54 @@ +shouldHaveType(AddressCloner::class); + } + + public function it_clones_values( + AddressInterface $originalAddress, + AddressInterface $newAddress, + ): void { + $dateTime = new \DateTime('now'); + $originalAddress->getCreatedAt()->willReturn($dateTime); + $originalAddress->getFirstName()->willReturn('firsName'); + $originalAddress->getLastName()->willReturn('lastName'); + $originalAddress->getCity()->willReturn('city'); + $originalAddress->getStreet()->willReturn('street'); + $originalAddress->getCompany()->willReturn('company name'); + $originalAddress->getPostcode()->willReturn('11-122'); + $originalAddress->getCountryCode()->willReturn('US'); + $originalAddress->getProvinceCode()->willReturn('code'); + $originalAddress->getProvinceName()->willReturn('provinceName'); + + $this->clone($originalAddress, $newAddress); + + $newAddress->setCreatedAt($dateTime)->shouldHaveBeenCalledTimes(1); + $newAddress->setFirstName('firsName')->shouldHaveBeenCalledTimes(1); + $newAddress->setLastName('lastName')->shouldHaveBeenCalledTimes(1); + $newAddress->setCity('city')->shouldHaveBeenCalledTimes(1); + $newAddress->setStreet('street')->shouldHaveBeenCalledTimes(1); + $newAddress->setCompany('company name')->shouldHaveBeenCalledTimes(1); + $newAddress->setPostcode('11-122')->shouldHaveBeenCalledTimes(1); + $newAddress->setCountryCode('US')->shouldHaveBeenCalledTimes(1); + $newAddress->setProvinceCode('code')->shouldHaveBeenCalledTimes(1); + $newAddress->setProvinceName('provinceName')->shouldHaveBeenCalledTimes(1); + } +} diff --git a/OpenMarketplace/spec/Component/Order/Cloner/AdjustmentClonerSpec.php b/OpenMarketplace/spec/Component/Order/Cloner/AdjustmentClonerSpec.php new file mode 100644 index 0000000..56de1a5 --- /dev/null +++ b/OpenMarketplace/spec/Component/Order/Cloner/AdjustmentClonerSpec.php @@ -0,0 +1,52 @@ +shouldHaveType(AdjustmentCloner::class); + } + + public function it_clones_adjustment( + AdjustmentInterface $originalAdjustment, + AdjustmentInterface $newAdjustment, + AdjustableInterface $adjustable + ): void { + $date = new \DateTime('now'); + $originalAdjustment->getType()->willReturn('type'); + $originalAdjustment->getOriginCode()->willReturn('code'); + $originalAdjustment->isNeutral()->willReturn(false); + $originalAdjustment->getLabel()->willReturn('label'); + $originalAdjustment->getDetails()->willReturn(['details']); + $originalAdjustment->getAmount()->willReturn(1); + $originalAdjustment->getCreatedAt()->willReturn($date); + $originalAdjustment->getUpdatedAt()->willReturn($date); + + $this->clone($originalAdjustment, $newAdjustment); + + $newAdjustment->setType('type')->shouldHaveBeenCalled(); + $newAdjustment->setOriginCode('code')->shouldHaveBeenCalled(); + $newAdjustment->setNeutral(false)->shouldHaveBeenCalled(); + $newAdjustment->setLabel('label')->shouldHaveBeenCalled(); + $newAdjustment->setDetails(['details'])->shouldHaveBeenCalled(); + $newAdjustment->setAmount(1)->shouldHaveBeenCalled(); + $newAdjustment->setCreatedAt($date)->shouldHaveBeenCalled(); + $newAdjustment->setUpdatedAt($date)->shouldHaveBeenCalled(); + } +} diff --git a/OpenMarketplace/spec/Component/Order/Cloner/OrderClonerSpec.php b/OpenMarketplace/spec/Component/Order/Cloner/OrderClonerSpec.php new file mode 100644 index 0000000..9587acd --- /dev/null +++ b/OpenMarketplace/spec/Component/Order/Cloner/OrderClonerSpec.php @@ -0,0 +1,101 @@ +beConstructedWith($entityManager, $addressCloner, $paymentCloner); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(OrderCloner::class); + $this->shouldImplement(OrderClonerInterface::class); + } + + public function it_clones_all_values( + EntityManagerInterface $entityManager, + AddressClonerInterface $addressCloner, + OrderInterface $originalOrder, + OrderInterface $newOrder, + AddressInterface $billingAddress, + AddressInterface $shippingAddress, + CustomerInterface $customer, + ChannelInterface $channel, + ShipmentInterface $shipment, + PaymentInterface $payment + ): void { + $date = new \DateTime('now'); + + $shipmentCollection = new ArrayCollection([$shipment->getWrappedObject()]); + $paymentCollection = new ArrayCollection([$payment->getWrappedObject()]); + $originalOrder->getBillingAddress()->willReturn($billingAddress); + $originalOrder->getShippingAddress()->willReturn($shippingAddress); + $originalOrder->getShipments()->willReturn($shipmentCollection); + $originalOrder->getPayments()->willReturn($paymentCollection); + + $addressCloner->clone(Argument::any(), Argument::any())->shouldBeCalled(); + + $originalOrder->getLocaleCode()->willReturn('US'); + $originalOrder->getChannel()->willReturn($channel); + $originalOrder->getCheckoutCompletedAt()->willReturn($date); + $originalOrder->getCreatedAt()->willReturn($date); + $originalOrder->getCurrencyCode()->willReturn('USD'); + $originalOrder->getCustomerIp()->willReturn('127.0.0.1'); + $originalOrder->getCreatedByGuest()->willReturn(false); + $originalOrder->getNotes()->willReturn(null); + $originalOrder->getState()->willReturn('state'); + $originalOrder->getCheckoutState()->willReturn('state'); + $originalOrder->getPaymentState()->willReturn('state'); + $originalOrder->getShippingState()->willReturn('state'); + $originalOrder->getCustomer()->willReturn($customer); + + $this->clone($originalOrder, $newOrder); + + $newOrder->setBillingAddress(Argument::any())->shouldHaveBeenCalledTimes(1); + $newOrder->setShippingAddress(Argument::any())->shouldHaveBeenCalledTimes(1); + $newOrder->setLocaleCode('US')->shouldHaveBeenCalledTimes(1); + $newOrder->setChannel($channel)->shouldHaveBeenCalledTimes(1); + $newOrder->setCheckoutCompletedAt($date)->shouldHaveBeenCalledTimes(1); + $newOrder->setCurrencyCode('USD')->shouldHaveBeenCalledTimes(1); + $newOrder->setCustomerIp('127.0.0.1')->shouldHaveBeenCalledTimes(1); + $newOrder->setCreatedByGuest(false)->shouldHaveBeenCalledTimes(1); + $newOrder->setNotes(null)->shouldHaveBeenCalledTimes(1); + $newOrder->setCreatedAt($date)->shouldHaveBeenCalledTimes(1); + $newOrder->setState('state')->shouldHaveBeenCalledTimes(1); + $newOrder->setCheckoutState('state')->shouldHaveBeenCalledTimes(1); + $newOrder->setPaymentState('state')->shouldHaveBeenCalledTimes(1); + $newOrder->setShippingState('state')->shouldHaveBeenCalledTimes(1); + $newOrder->setCustomer($customer)->shouldHaveBeenCalledTimes(1); + $entityManager->flush()->shouldHaveBeenCalledTimes(1); + } +} diff --git a/OpenMarketplace/spec/Component/Order/Cloner/OrderItemClonerSpec.php b/OpenMarketplace/spec/Component/Order/Cloner/OrderItemClonerSpec.php new file mode 100644 index 0000000..20c58ef --- /dev/null +++ b/OpenMarketplace/spec/Component/Order/Cloner/OrderItemClonerSpec.php @@ -0,0 +1,74 @@ +beConstructedWith($cloner, $itemUnitCloner, $entityManager); + } + + public function it_is_initializable() + { + $this->shouldHaveType(OrderItemCloner::class); + } + + public function it_clones_order_item( + AdjustmentClonerInterface $cloner, + OrderItemUnitClonerInterface $itemUnitCloner, + EntityManagerInterface $entityManager, + OrderItemInterface $originalItem, + OrderItemInterface $newItem, + ProductVariantInterface $productVariant, + ShipmentInterface $shipment, + OrderItemUnitInterface $unit, + AdjustmentInterface $adjustment, + ): void { + $unitCollection = new ArrayCollection([$unit->getWrappedObject()]); + $adjustmentCollection = new ArrayCollection([$adjustment->getWrappedObject()]); + + $originalItem->getUnits()->willReturn($unitCollection); + $originalItem->getAdjustments()->willReturn($adjustmentCollection); + + $originalItem->getOriginalUnitPrice()->willReturn(111); + $originalItem->getProductName()->willReturn('name'); + $originalItem->getVariant()->willReturn($productVariant); + $originalItem->getVariantName()->willReturn('variant_name'); + $originalItem->getUnitPrice()->willReturn(111); + $originalItem->getVersion()->willReturn(1); + + $this->clone($originalItem, $newItem, $shipment); + + $newItem->setOriginalUnitPrice(111); + $newItem->setProductName('name'); + $newItem->setVariant($productVariant); + $newItem->setVariantName('variant_name'); + $newItem->setUnitPrice(111); + $newItem->setVersion(1); + } +} diff --git a/OpenMarketplace/spec/Component/Order/Cloner/PaymentClonerSpec.php b/OpenMarketplace/spec/Component/Order/Cloner/PaymentClonerSpec.php new file mode 100644 index 0000000..b6ba6bd --- /dev/null +++ b/OpenMarketplace/spec/Component/Order/Cloner/PaymentClonerSpec.php @@ -0,0 +1,48 @@ +shouldHaveType(PaymentCloner::class); + } + + public function it_clones_payment( + PaymentInterface $newPayment, + PaymentInterface $originalPayment, + PaymentMethodInterface $paymentMethod + ): void { + $date = new \DateTime('now'); + $originalPayment->getCreatedAt()->willReturn($date); + $originalPayment->getCurrencyCode()->willReturn('USD'); + $originalPayment->getMethod()->willReturn($paymentMethod); + $originalPayment->getState()->willReturn('new'); + $originalPayment->getDetails()->willReturn(['details']); + $originalPayment->getUpdatedAt()->willReturn($date); + + $this->clone($originalPayment, $newPayment); + + $newPayment->setCreatedAt($date)->shouldHaveBeenCalledTimes(1); + $newPayment->setCurrencyCode('USD')->shouldHaveBeenCalledTimes(1); + $newPayment->setMethod($paymentMethod)->shouldHaveBeenCalledTimes(1); + $newPayment->setDetails(['details'])->shouldHaveBeenCalledTimes(1); + $newPayment->setState('new')->shouldHaveBeenCalledTimes(1); + $newPayment->setUpdatedAt($date)->shouldHaveBeenCalledTimes(1); + } +} diff --git a/OpenMarketplace/spec/Component/Order/Cloner/ShipmentClonerSpec.php b/OpenMarketplace/spec/Component/Order/Cloner/ShipmentClonerSpec.php new file mode 100644 index 0000000..164d9ee --- /dev/null +++ b/OpenMarketplace/spec/Component/Order/Cloner/ShipmentClonerSpec.php @@ -0,0 +1,61 @@ +beConstructedWith($adjustmentCloner); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(ShipmentCloner::class); + } + + public function it_clones_shipment( + ShipmentInterface $originalShipment, + ShipmentInterface $newShipment, + ShippingMethodInterface $shippingMethod, + AdjustmentInterface $adjustment, + AdjustmentClonerInterface $adjustmentCloner + ): void { + $adjustmentCollection = new ArrayCollection([$adjustment->getWrappedObject(), $adjustment->getWrappedObject()]); + $date = new \DateTime('now'); + + $originalShipment->getState()->willReturn('new'); + $originalShipment->getUpdatedAt()->willReturn($date); + $originalShipment->getCreatedAt()->willReturn($date); + $originalShipment->getMethod()->willReturn($shippingMethod); + $originalShipment->getAdjustments()->willReturn($adjustmentCollection); + + $this->clone($originalShipment, $newShipment); + + $newShipment->setState('new')->shouldHaveBeenCalledTimes(1); + $newShipment->setUpdatedAt($date)->shouldHaveBeenCalledTimes(1); + $newShipment->setCreatedAt($date)->shouldHaveBeenCalledTimes(1); + $newShipment->setMethod($shippingMethod)->shouldHaveBeenCalledTimes(1); + + $adjustmentsCount = $adjustmentCollection->count(); + $adjustmentCloner->clone($adjustment, Argument::any())->shouldHaveBeenCalledTimes($adjustmentsCount); + } +} diff --git a/OpenMarketplace/spec/Component/Order/CommissionCalculator/VendorGrossCommissionCalculatorSpec.php b/OpenMarketplace/spec/Component/Order/CommissionCalculator/VendorGrossCommissionCalculatorSpec.php new file mode 100644 index 0000000..bcb39b1 --- /dev/null +++ b/OpenMarketplace/spec/Component/Order/CommissionCalculator/VendorGrossCommissionCalculatorSpec.php @@ -0,0 +1,50 @@ +shouldHaveType(VendorGrossCommissionCalculator::class); + $this->shouldImplement(VendorCommissionCalculatorInterface::class); + } + + public function it_returns_false_on_unsupported_commission_type(OrderInterface $order, VendorInterface $vendor): void + { + $order->getVendor()->willReturn($vendor); + $vendor->getCommissionType()->willReturn('net'); + $this->supports($order)->shouldReturn(false); + } + + public function it_throws_exception_on_primary_order(OrderInterface $order): void + { + $order->isPrimary()->willReturn(true); + $this->shouldThrow(\Exception::class) + ->during('calculate', [$order]); + } + + public function it_calculates_valid_commission(OrderInterface $order, VendorInterface $vendor): void + { + $order->isPrimary()->willReturn(false); + $order->getVendor()->willReturn($vendor); + $vendor->getCommission()->willReturn(10); + $order->getTotal()->willReturn(10000); + $this->calculate($order)->shouldReturn(1000); + } +} diff --git a/OpenMarketplace/spec/Component/Order/CommissionCalculator/VendorNetCommissionCalculatorSpec.php b/OpenMarketplace/spec/Component/Order/CommissionCalculator/VendorNetCommissionCalculatorSpec.php new file mode 100644 index 0000000..1322ff8 --- /dev/null +++ b/OpenMarketplace/spec/Component/Order/CommissionCalculator/VendorNetCommissionCalculatorSpec.php @@ -0,0 +1,50 @@ +shouldHaveType(VendorNetCommissionCalculator::class); + $this->shouldImplement(VendorCommissionCalculatorInterface::class); + } + + public function it_returns_false_on_unsupported_commission_type(OrderInterface $order, VendorInterface $vendor): void + { + $order->getVendor()->willReturn($vendor); + $vendor->getCommissionType()->willReturn('gross'); + $this->supports($order)->shouldReturn(false); + } + + public function it_throws_exception_on_primary_order(OrderInterface $order): void + { + $order->isPrimary()->willReturn(true); + $this->shouldThrow(\Exception::class) + ->during('calculate', [$order]); + } + + public function it_calculates_valid_commission(OrderInterface $order, VendorInterface $vendor): void + { + $order->isPrimary()->willReturn(false); + $order->getVendor()->willReturn($vendor); + $vendor->getCommission()->willReturn(10); + $order->getItemsTotal()->willReturn(10000); + $this->calculate($order)->shouldReturn(1000); + } +} diff --git a/OpenMarketplace/spec/Component/Order/EventListener/CalculateOrderCommissionListenerSpec.php b/OpenMarketplace/spec/Component/Order/EventListener/CalculateOrderCommissionListenerSpec.php new file mode 100644 index 0000000..c28a125 --- /dev/null +++ b/OpenMarketplace/spec/Component/Order/EventListener/CalculateOrderCommissionListenerSpec.php @@ -0,0 +1,62 @@ +beConstructedWith( + $commissionCalculators, + $entityManager + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(CalculateOrderCommissionListener::class); + } + + public function it_throws_exception_about_lack_of_calculator( + \IteratorAggregate $commissionCalculators, + PostSplitOrderEvent $event, + OrderInterface $order + ): void { + $commissionCalculators->getIterator()->willReturn(new ArrayCollection([])); + $event->getOrders()->willReturn([$order]); + $this->shouldThrow(\RuntimeException::class)->during('calculate', [$event]); + } + + public function it_calculates_commission( + \IteratorAggregate $commissionCalculators, + PostSplitOrderEvent $event, + OrderInterface $order, + VendorCommissionCalculatorInterface $commissionCalculator + ): void { + $commissionCalculators->getIterator()->willReturn(new ArrayCollection([$commissionCalculator->getWrappedObject()])); + $event->getOrders()->willReturn([$order]); + $commissionCalculator->supports($order)->willReturn(true); + $commissionCalculator->calculate($order)->willReturn(1000); + $order->setCommissionTotal(1000)->shouldBeCalled(); + $this->calculate($event); + } +} diff --git a/OpenMarketplace/spec/Component/Order/Factory/ShipmentFactorySpec.php b/OpenMarketplace/spec/Component/Order/Factory/ShipmentFactorySpec.php new file mode 100644 index 0000000..b5084e5 --- /dev/null +++ b/OpenMarketplace/spec/Component/Order/Factory/ShipmentFactorySpec.php @@ -0,0 +1,101 @@ +beConstructedWith( + Shipment::class, + $defaultVendorShippingMethodResolver, + $defaultShippingMethodResolver + ) + ; + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(ShipmentFactory::class); + $this->shouldImplement(ShipmentFactoryInterface::class); + } + + public function it_creates_object(): void + { + $this->createNew()->shouldBeAnInstanceOf(Shipment::class); + } + + public function it_creates_object_with_order(OrderInterface $order): void + { + $shipment = $this->createNewWithOrder($order); + $shipment->shouldBeAnInstanceOf(Shipment::class); + $shipment->getOrder()->shouldBe($order); + } + + public function it_tries_to_create_object_with_default_shipment_and_vendor( + OrderInterface $order, + ChannelInterface $channel, + VendorInterface $vendor, + VendorShippingMethodInterface $vendorShippingMethod, + ShippingMethodInterface $shippingMethod, + VendorShippingMethodsResolverInterface $defaultVendorShippingMethodResolver + ): void { + $order->getChannel()->willReturn($channel); + + $defaultVendorShippingMethodResolver + ->getDefaultShippingMethod($vendor, $channel) + ->willReturn($vendorShippingMethod) + ; + $vendorShippingMethod->getShippingMethod()->willReturn($shippingMethod); + + $shipment = $this->tryCreateNewWithOrderVendorAndDefaultShipment($order, $vendor); + + $shipment->getOrder()->shouldBe($order); + $shipment->getVendor()->shouldBe($vendor); + $shipment->getMethod()->shouldBe($shippingMethod); + } + + public function it_tries_to_create_object_with_default_shipment_and_without_vendor( + OrderInterface $order, + ChannelInterface $channel, + ShippingMethodInterface $shippingMethod, + DefaultShippingMethodResolverInterface $defaultShippingMethodResolver + ): void { + $order->getChannel()->willReturn($channel); + + $defaultShippingMethodResolver + ->getDefaultShippingMethod(Argument::type(Shipment::class)) + ->willReturn($shippingMethod) + ; + + $shipment = $this->tryCreateNewWithOrderVendorAndDefaultShipment($order, null); + + $shipment->getOrder()->shouldBe($order); + $shipment->getMethod()->shouldBe($shippingMethod); + } +} diff --git a/OpenMarketplace/spec/Component/Order/OrderManagerSpec.php b/OpenMarketplace/spec/Component/Order/OrderManagerSpec.php new file mode 100644 index 0000000..e409d46 --- /dev/null +++ b/OpenMarketplace/spec/Component/Order/OrderManagerSpec.php @@ -0,0 +1,107 @@ +beConstructedWith( + $factory, + $cloner, + $shipmentCloner, + $entityManager, + $orderItemCloner, + $itemFactory, + $shipmentFactory + ) + ; + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(OrderManager::class); + } + + public function it_generate_order_with_given_item( + OrderInterface $order, + OrderItemInterface $orderItem, + VendorInterface $itemVendor, + OrderInterface $newOrder, + OrderFactoryInterface $factory, + OrderItemFactoryInterface $itemFactory, + ShipmentInterface $shipment, + ShipmentInterface $newShipment, + OrderItemInterface $newItem, + ShipmentFactoryInterface $shipmentFactory, + ShipmentClonerInterface $shipmentCloner + ): void { + $factory->createNew()->willReturn($newOrder); + $itemFactory->createNew()->willReturn($newItem); + $order->getShipmentByVendor($itemVendor)->willReturn($shipment); + $shipmentFactory->createNew()->willReturn($newShipment); + $newShipment->setOrder($newOrder)->shouldBeCalled(); + $shipmentCloner->clone($shipment, $newShipment)->shouldBeCalled(); + $newOrder->addShipment($newShipment)->shouldBeCalled(); + + $this->generateNewSecondaryOrder($order, $itemVendor, $orderItem)->shouldReturn($newOrder); + + $newOrder->addItem($newItem)->shouldHaveBeenCalledTimes(1); + $newOrder->setVendor($itemVendor)->shouldHaveBeenCalledTimes(1); + $newOrder->setPrimaryOrder($order)->shouldHaveBeenCalledTimes(1); + $newOrder->setMode(OrderInterface::SECONDARY_ORDER_MODE)->shouldHaveBeenCalledTimes(1); + } + + public function it_adds_item_into_order( + OrderInterface $order, + OrderInterface $order2, + OrderItemInterface $orderItem, + VendorInterface $itemVendor, + OrderItemFactoryInterface $itemFactory, + ShipmentInterface $shipment, + OrderItemInterface $newItem, + ): void { + $orders = [$order, $order2]; + $shipments = new ArrayCollection([$shipment->getWrappedObject()]); + $itemFactory->createNew()->willReturn($newItem); + + $order->getVendor()->willReturn($itemVendor); + $order->getShipments()->willReturn($shipments); + + $order->addItem($newItem)->shouldBeCalledOnce(); + + $this->addItemIntoSecondaryOrder($orders, $itemVendor, $orderItem); + } +} diff --git a/OpenMarketplace/spec/Component/Order/Processor/SplitOrderByVendorProcessorSpec.php b/OpenMarketplace/spec/Component/Order/Processor/SplitOrderByVendorProcessorSpec.php new file mode 100644 index 0000000..3b1aa43 --- /dev/null +++ b/OpenMarketplace/spec/Component/Order/Processor/SplitOrderByVendorProcessorSpec.php @@ -0,0 +1,126 @@ +beConstructedWith( + $orderManager, + $paymentRefresher, + $eventDispatcher + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(SplitOrderByVendorProcessor::class); + } + + public function it_creates_at_least_one_secondary_order_for_the_first_time( + OrderInterface $order, + PaymentInterface $payment, + OrderItemInterface $orderItem, + OrderInterface $subOrder, + VendorInterface $vendor, + OrderManagerInterface $orderManager, + PaymentRefresherInterface $paymentRefresher, + EventDispatcherInterface $eventDispatcher + ): void { + $order->isPrimary()->willReturn(false); + $order->getSecondaryOrders()->willReturn(new ArrayCollection([])); + + $eventDispatcher->dispatch(Argument::any(), Argument::any())->willReturn((object) []); + $orderItemCollection = new ArrayCollection([$orderItem->getWrappedObject()]); + $paymentCollection = new ArrayCollection([$payment->getWrappedObject()]); + $order->getItems()->willReturn($orderItemCollection); + $orderItem->getProductOwner()->willReturn($vendor); + $order->getPayments()->willReturn($paymentCollection); + $order->getTotal()->willReturn(100); + $subOrder->getVendor()->willReturn(null); + $order->getVendor()->willReturn(null); + $orderManager->generateNewSecondaryOrder($order, $vendor, $orderItem)->willReturn($subOrder); + + $this->process($order); + + $paymentRefresher->refreshPayment($subOrder)->shouldHaveBeenCalled(); + $eventDispatcher->dispatch(Argument::any(), Argument::any())->shouldHaveBeenCalled(); + } + + public function it_quickly_returns_already_splitted_orders( + OrderInterface $order, + OrderInterface $subOrder, + EventDispatcherInterface $eventDispatcher + ): void { + $order->isPrimary()->willReturn(true); + $order->getSecondaryOrders()->willReturn(new ArrayCollection([$subOrder->getWrappedObject()])); + + $eventDispatcher->dispatch(Argument::any(), Argument::any())->shouldNotBeCalled(); + + $this->process($order); + } + + public function it_creates_2_secondary_orders_for_products_from_different_vendors( + OrderInterface $order, + PaymentInterface $payment, + OrderItemInterface $orderItem, + OrderItemInterface $secondItem, + OrderInterface $subOrder, + OrderInterface $subOrder2, + VendorInterface $vendor, + VendorInterface $vendor2, + OrderManagerInterface $orderManager, + PaymentRefresherInterface $paymentRefresher, + EventDispatcherInterface $eventDispatcher + ): void { + $order->isPrimary()->willReturn(false); + $order->getSecondaryOrders()->willReturn(new ArrayCollection([])); + + $eventDispatcher->dispatch(Argument::any(), Argument::any())->willReturn((object) []); + $orderItemCollection = new ArrayCollection([$orderItem->getWrappedObject(), $secondItem->getWrappedObject()]); + $paymentCollection = new ArrayCollection([$payment->getWrappedObject()]); + $order->getItems()->willReturn($orderItemCollection); + + $orderItem->getProductOwner()->willReturn($vendor); + $secondItem->getProductOwner()->willReturn($vendor2); + $order->getPayments()->willReturn($paymentCollection); + $order->getTotal()->willReturn(100); + + $order->getVendor()->willReturn(null); + $subOrder->getVendor()->willReturn($vendor); + $subOrder2->getVendor()->willReturn($vendor2); + + $orderManager->generateNewSecondaryOrder($order, $vendor, $orderItem)->willReturn($subOrder); + $orderManager->generateNewSecondaryOrder($order, $vendor2, $secondItem)->willReturn($subOrder2); + + $this->process($order); + + $paymentRefresher->refreshPayment($subOrder)->shouldHaveBeenCalled(); + $eventDispatcher->dispatch(Argument::any(), Argument::any())->shouldHaveBeenCalled(); + } +} diff --git a/OpenMarketplace/spec/Component/Order/Refresher/PaymentRefresherSpec.php b/OpenMarketplace/spec/Component/Order/Refresher/PaymentRefresherSpec.php new file mode 100644 index 0000000..bd06fef --- /dev/null +++ b/OpenMarketplace/spec/Component/Order/Refresher/PaymentRefresherSpec.php @@ -0,0 +1,53 @@ +beConstructedWith($entityManager); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(PaymentRefresher::class); + } + + public function it_refreshes_payment( + OrderInterface $secondaryOrder, + OrderInterface $primaryOrder, + PaymentInterface $secondaryOrderPayment, + PaymentInterface $primaryOrderPayment, + PaymentMethodInterface $paymentMethod, + ): void { + $secondaryOrder->getTotal()->willReturn(100); + $secondaryOrder->getPrimaryOrder()->willReturn($primaryOrder); + $secondaryOrder->getLastPayment()->willReturn($secondaryOrderPayment); + $primaryOrder->getLastPayment()->willReturn($primaryOrderPayment); + $primaryOrderPayment->getMethod()->willReturn($paymentMethod); + $secondaryOrderPayment->setAmount(100); + + $secondaryOrder->recalculateItemsTotal()->shouldBeCalledOnce(); + $secondaryOrder->recalculateAdjustmentsTotal()->shouldBeCalledOnce(); + $secondaryOrderPayment->setMethod($paymentMethod)->shouldBeCalledOnce(); + + $this->refreshPayment($secondaryOrder); + } +} diff --git a/OpenMarketplace/spec/Component/Order/Resolver/VendorShippingMethodsResolverSpec.php b/OpenMarketplace/spec/Component/Order/Resolver/VendorShippingMethodsResolverSpec.php new file mode 100644 index 0000000..0d8faac --- /dev/null +++ b/OpenMarketplace/spec/Component/Order/Resolver/VendorShippingMethodsResolverSpec.php @@ -0,0 +1,93 @@ +beConstructedWith($vendorShippingMethodRepository, $shippingMethodsResolver); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(VendorShippingMethodsResolver::class); + $this->shouldImplement(VendorShippingMethodsResolverInterface::class); + } + + public function it_returns_default_shipping_method_for_vendor( + VendorInterface $vendor, + ChannelInterface $channel, + VendorShippingMethodInterface $vendorShippingMethod, + VendorShippingMethodRepositoryInterface $vendorShippingMethodRepository + ): void { + $vendorShippingMethodRepository->findEnabledForChannel($vendor, $channel)->willReturn([$vendorShippingMethod]); + + $this->getDefaultShippingMethod($vendor, $channel)->shouldReturn($vendorShippingMethod); + } + + public function it_does_not_return_default_shipping_method_for_vendor( + VendorInterface $vendor, + ChannelInterface $channel, + VendorShippingMethodRepositoryInterface $vendorShippingMethodRepository + ): void { + $vendorShippingMethodRepository->findEnabledForChannel($vendor, $channel)->willReturn([]); + + $this + ->shouldThrow(UnresolvedDefaultShippingMethodException::class) + ->duringGetDefaultShippingMethod($vendor, $channel) + ; + } + + public function it_returns_default_shipping_methods_for_shipment_with_vendor( + ShipmentInterface $subject, + ShippingMethodsResolverInterface $shippingMethodsResolver, + VendorShippingMethodRepositoryInterface $vendorShippingMethodRepository, + VendorInterface $vendor, + OrderInterface $order, + ChannelInterface $channel, + VendorShippingMethodInterface $vendorShippingMethod1, + VendorShippingMethodInterface $vendorShippingMethod2, + ShippingMethodInterface $shippingMethod1, + ShippingMethodInterface $shippingMethod2 + ): void { + $subject->hasVendor()->willReturn(true); + $subject->getVendor()->willReturn($vendor); + $subject->getOrder()->willReturn($order); + $order->getChannel()->willReturn($channel); + $vendorShippingMethod1->getShippingMethod()->willReturn($shippingMethod1); + $vendorShippingMethod2->getShippingMethod()->willReturn($shippingMethod2); + + $shippingMethodsResolver->getSupportedMethods($subject)->shouldNotBeCalled(); + $vendorShippingMethodRepository + ->findEnabledForChannel($vendor, $channel) + ->willReturn([$vendorShippingMethod1, $vendorShippingMethod2]) + ; + + $this->getSupportedMethods($subject)->shouldReturn([$shippingMethod1, $shippingMethod2]); + } +} diff --git a/OpenMarketplace/spec/Component/Override/Sylius/Bundle/ApiBundle/ApiPlatform/Bridge/Symfony/Routing/RouteNameResolverSpec.php b/OpenMarketplace/spec/Component/Override/Sylius/Bundle/ApiBundle/ApiPlatform/Bridge/Symfony/Routing/RouteNameResolverSpec.php new file mode 100644 index 0000000..6927448 --- /dev/null +++ b/OpenMarketplace/spec/Component/Override/Sylius/Bundle/ApiBundle/ApiPlatform/Bridge/Symfony/Routing/RouteNameResolverSpec.php @@ -0,0 +1,261 @@ +beConstructedWith($router, $pathPrefixProvider); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(RouteNameResolver::class); + $this->shouldHaveType(RouteNameResolverInterface::class); + } + + public function it_gets_route_name_for_item_route_with_no_matching_route( + RouterInterface $router, + ): void { + $routeCollection = new RouteCollection(); + $routeCollection->add('certain_collection_route', new Route('/certain/collection/path', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_collection_operation_name' => 'certain_collection_op', + ])); + + $router->getRouteCollection()->willReturn($routeCollection); + + $this->shouldThrow(\InvalidArgumentException::class) + ->during('getRouteName', ['AppBundle\Entity\User', OperationType::ITEM]) + ; + } + + public function it_gets_route_name_for_item_route( + RouterInterface $router, + ): void { + $routeCollection = new RouteCollection(); + $routeCollection->add('certain_collection_route', new Route('/certain/collection/path', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_collection_operation_name' => 'certain_collection_op', + ])); + $routeCollection->add('certain_item_route', new Route('/certain/item/path/{id}', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_item_operation_name' => 'certain_item_op', + ])); + + $router->getRouteCollection()->willReturn($routeCollection); + + $this->getRouteName('AppBundle\Entity\User', OperationType::ITEM)->shouldReturn('certain_item_route'); + } + + public function it_gets_route_name_for_collection_route_with_no_matching_route( + RouterInterface $router, + ): void { + $routeCollection = new RouteCollection(); + $routeCollection->add('certain_item_route', new Route('/certain/item/path/{id}', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_item_operation_name' => 'certain_item_op', + ])); + + $router->getRouteCollection()->willReturn($routeCollection); + + $this->shouldThrow(\InvalidArgumentException::class) + ->during('getRouteName', ['AppBundle\Entity\User', OperationType::COLLECTION]) + ; + } + + public function it_gets_route_name_for_collection_route( + RouterInterface $router, + ): void { + $routeCollection = new RouteCollection(); + $routeCollection->add('certain_item_route', new Route('/certain/item/path/{id}', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_item_operation_name' => 'certain_item_op', + ])); + $routeCollection->add('certain_collection_route', new Route('/certain/collection/path', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_collection_operation_name' => 'certain_collection_op', + ])); + + $router->getRouteCollection()->willReturn($routeCollection); + + $this->getRouteName('AppBundle\Entity\User', OperationType::COLLECTION)->shouldReturn('certain_collection_route'); + } + + public function it_gets_route_name_for_subresource_route( + RouterInterface $router, + ): void { + $routeCollection = new RouteCollection(); + $routeCollection->add('a_certain_subresource_route', new Route('/a/certain/item/path/{id}', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_subresource_operation_name' => 'certain_other_item_op', + '_api_subresource_context' => ['identifiers' => ['id' => ['bar', 'id']]], + ])); + $routeCollection->add('b_certain_subresource_route', new Route('/b/certain/item/path/{id}', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_subresource_operation_name' => 'certain_item_op', + '_api_subresource_context' => ['identifiers' => ['id' => ['foo', 'id']]], + ])); + $routeCollection->add('certain_collection_route', new Route('/certain/collection/path', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_collection_operation_name' => 'certain_collection_op', + ])); + + $router->getRouteCollection()->willReturn($routeCollection); + + $this->getRouteName( + 'AppBundle\Entity\User', + OperationType::SUBRESOURCE, + ['subresource_resources' => ['foo' => 1]] + )->shouldReturn('b_certain_subresource_route'); + } + + public function it_gets_route_name_for_item_route_if_only_one( + RouterInterface $router, + PathPrefixProviderInterface $pathPrefixProvider, + ): void { + $routeCollection = new RouteCollection(); + $routeCollection->add('get_collection', new Route('/admin/item/path', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_collection_operation_name' => 'get_collection', + ])); + $routeCollection->add('get_item', new Route('/item/path/{id}', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_item_operation_name' => 'get_item', + ])); + + $router->getRouteCollection()->willReturn($routeCollection); + + $this->getRouteName('AppBundle\Entity\User', OperationType::ITEM)->shouldReturn('get_item'); + } + + public function it_gets_route_name_if_has_path_prefix_null( + RouterInterface $router, + PathPrefixProviderInterface $pathPrefixProvider, + ): void { + $routeCollection = new RouteCollection(); + $routeCollection->add('admin_get', new Route('/admin/item/path/{id}', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_item_operation_name' => 'get_item', + ])); + + $routeCollection->add('vendor_get', new Route('/vendor/item/path/{id}', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_item_operation_name' => 'get_item', + ])); + + $pathPrefixProvider->getPathPrefix('/admin/item/path/{id}')->willReturn(null); + $pathPrefixProvider->getPathPrefix('/vendor/item/path/{id}')->willReturn('vendor'); + + $router->getRouteCollection()->willReturn($routeCollection); + + $this->getRouteName('AppBundle\Entity\User', OperationType::ITEM)->shouldReturn('admin_get'); + } + + public function it_gets_admin_route_name_for_item_route_if_current_prefix_admin( + RouterInterface $router, + PathPrefixProviderInterface $pathPrefixProvider, + ): void { + $routeCollection = new RouteCollection(); + $routeCollection->add('admin_get', new Route('/admin/item/path/{id}', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_item_operation_name' => 'get_item', + ])); + + $routeCollection->add('vendor_get', new Route('/vendor/item/path/{id}', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_item_operation_name' => 'get_item', + ])); + $routeCollection->add('shop_get', new Route('/shop/item/path/{id}', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_item_operation_name' => 'get_item', + ])); + + $pathPrefixProvider->getPathPrefix('/admin/item/path/{id}')->willReturn('admin'); + $pathPrefixProvider->getPathPrefix('/vendor/item/path/{id}')->willReturn('vendor'); + $pathPrefixProvider->getPathPrefix('/shop/item/path/{id}')->willReturn('shop'); + $pathPrefixProvider->getCurrentPrefix()->willReturn('admin'); + + $router->getRouteCollection()->willReturn($routeCollection); + + $this->getRouteName('AppBundle\Entity\User', OperationType::ITEM)->shouldReturn('admin_get'); + } + + public function it_gets_shop_route_name_for_item_route_if_current_prefix_shop( + RouterInterface $router, + PathPrefixProviderInterface $pathPrefixProvider, + ): void { + $routeCollection = new RouteCollection(); + $routeCollection->add('admin_get', new Route('/admin/item/path/{id}', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_item_operation_name' => 'get_item', + ])); + + $routeCollection->add('vendor_get', new Route('/vendor/item/path/{id}', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_item_operation_name' => 'get_item', + ])); + $routeCollection->add('shop_get', new Route('/shop/item/path/{id}', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_item_operation_name' => 'get_item', + ])); + + $pathPrefixProvider->getPathPrefix('/admin/item/path/{id}')->willReturn('admin'); + $pathPrefixProvider->getPathPrefix('/vendor/item/path/{id}')->willReturn('vendor'); + $pathPrefixProvider->getPathPrefix('/shop/item/path/{id}')->willReturn('shop'); + $pathPrefixProvider->getCurrentPrefix()->willReturn('shop'); + + $router->getRouteCollection()->willReturn($routeCollection); + + $this->getRouteName('AppBundle\Entity\User', OperationType::ITEM)->shouldReturn('shop_get'); + } + + public function it_gets_vendor_route_name_for_item_route_if_current_prefix_contains_vendor( + RouterInterface $router, + PathPrefixProviderInterface $pathPrefixProvider, + ): void { + $routeCollection = new RouteCollection(); + $routeCollection->add('admin_get', new Route('/admin/item/path/{id}', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_item_operation_name' => 'get_item', + ])); + + $routeCollection->add('vendor_get', new Route('/vendor/item/path/{id}', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_item_operation_name' => 'get_item', + ])); + $routeCollection->add('shop_get', new Route('/shop/item/path/{id}', [ + '_api_resource_class' => 'AppBundle\Entity\User', + '_api_item_operation_name' => 'get_item', + ])); + + $pathPrefixProvider->getPathPrefix('/admin/item/path/{id}')->willReturn('admin'); + $pathPrefixProvider->getPathPrefix('/vendor/item/path/{id}')->willReturn('vendor'); + $pathPrefixProvider->getPathPrefix('/shop/item/path/{id}')->willReturn('shop'); + $pathPrefixProvider->getCurrentPrefix()->willReturn('shop_vendor'); + + $router->getRouteCollection()->willReturn($routeCollection); + + $this->getRouteName('AppBundle\Entity\User', OperationType::ITEM)->shouldReturn('vendor_get'); + } +} diff --git a/OpenMarketplace/spec/Component/Override/Sylius/Bundle/OrderBundle/NumberAssigner/OrderNumberAssignerSpec.php b/OpenMarketplace/spec/Component/Override/Sylius/Bundle/OrderBundle/NumberAssigner/OrderNumberAssignerSpec.php new file mode 100644 index 0000000..28a4741 --- /dev/null +++ b/OpenMarketplace/spec/Component/Override/Sylius/Bundle/OrderBundle/NumberAssigner/OrderNumberAssignerSpec.php @@ -0,0 +1,53 @@ +beConstructedWith( + $orderNumberAssigner + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(OrderNumberAssigner::class); + } + + public function it_implements_interface(): void + { + $this->shouldImplement(BitbagOrderNumberAssignerInterface::class); + } + + public function it_does_not_increment_sequence_on_primary_order( + OrderInterface $order, + OrderNumberAssignerInterface $decoratedOrderNumberAssigner + ) { + $order->isPrimary()->willReturn(true); + $order->getNumber()->willReturn(null); + + $this->assignNumber($order); + + $order->setNumber(Argument::any())->shouldNotBeCalled(); + $decoratedOrderNumberAssigner->assignNumber($order)->shouldNotBeCalled(); + } +} diff --git a/OpenMarketplace/spec/Component/Override/Sylius/Component/Core/OrderProcessing/OrderShipmentProcessorSpec.php b/OpenMarketplace/spec/Component/Override/Sylius/Component/Core/OrderProcessing/OrderShipmentProcessorSpec.php new file mode 100644 index 0000000..58d46a9 --- /dev/null +++ b/OpenMarketplace/spec/Component/Override/Sylius/Component/Core/OrderProcessing/OrderShipmentProcessorSpec.php @@ -0,0 +1,128 @@ +beConstructedWith( + $shipmentFactory, + $shipmentUnitsRecalculator + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(OrderShipmentProcessor::class); + $this->shouldImplement(OrderShipmentProcessorInterface::class); + } + + public function it_does_nothing_because_of_wrong_state( + OrderInterface $order, + ): void { + $order->getState()->willReturn(BaseOrderInterface::STATE_NEW); + + $order->isEmpty()->shouldNotBeCalled(); + $order->isShippingRequired()->shouldNotBeCalled(); + $order->getVendorsFromOrderItems()->shouldNotBeCalled(); + + $this->process($order); + } + + public function it_removes_shipment_because_order_is_empty( + OrderInterface $order, + ): void { + $order->getState()->willReturn(BaseOrderInterface::STATE_CART); + + $order->isEmpty()->willReturn(false); + $order->isShippingRequired()->willReturn(false); + $order->removeShipments()->shouldBeCalled(); + $order->getVendorsFromOrderItems()->shouldNotBeCalled(); + + $this->process($order); + } + + public function it_adds_vendor_shipment_to_order( + ShipmentFactoryInterface $shipmentFactory, + OrderInterface $order, + VendorInterface $vendor, + ShipmentInterface $shipment, + ShipmentUnitsRecalculatorInterface $shipmentUnitsRecalculator + ): void { + $order->getState()->willReturn(BaseOrderInterface::STATE_CART); + + $order->isEmpty()->willReturn(false); + $order->isShippingRequired()->willReturn(true); + $order->removeShipments()->shouldNotBeCalled(); + + $order->getVendorsFromOrderItems()->willReturn([$vendor]); + + $order->hasVendorShipment($vendor)->willReturn(false); + $order->hasShippableItemsWithVendor($vendor)->willReturn(true); + + $shipmentFactory + ->tryCreateNewWithOrderVendorAndDefaultShipment($order, $vendor) + ->willReturn($shipment) + ; + $order->addShipment($shipment)->shouldBeCalled(); + + $shipmentUnitsRecalculator->recalculateShipmentUnits($order)->shouldBeCalled(); + + $this->process($order); + } + + public function it_adds_shipment_for_items_without_vendor( + ShipmentFactoryInterface $shipmentFactory, + OrderInterface $order, + ShipmentInterface $shipment, + ShipmentUnitsRecalculatorInterface $shipmentUnitsRecalculator + ): void { + $order->getState()->willReturn(BaseOrderInterface::STATE_CART); + + $order->isEmpty()->willReturn(false); + $order->isShippingRequired()->willReturn(true); + $order->removeShipments()->shouldNotBeCalled(); + + $order->getVendorsFromOrderItems()->willReturn([null]); + + $order->hasVendorShipment(null)->willReturn(false); + $order->hasShippableItemsWithVendor(null)->willReturn(true); + $order->addShipment($shipment)->shouldBeCalled(); + + $order->getShipments()->willReturn(new ArrayCollection()); + + $shipmentFactory + ->tryCreateNewWithOrderVendorAndDefaultShipment($order, null) + ->willReturn($shipment) + ; + + $shipmentUnitsRecalculator->recalculateShipmentUnits($order)->shouldBeCalled(); + + $order->getShipmentWithoutVendor()->willReturn(null); + + $this->process($order); + } +} diff --git a/OpenMarketplace/spec/Component/Product/Factory/ProductAttributeFactorySpec.php b/OpenMarketplace/spec/Component/Product/Factory/ProductAttributeFactorySpec.php new file mode 100644 index 0000000..c2bed41 --- /dev/null +++ b/OpenMarketplace/spec/Component/Product/Factory/ProductAttributeFactorySpec.php @@ -0,0 +1,47 @@ +shouldHaveType(ProductAttributeFactoryInterface::class); + } + + public function it_returns_valid_object( + DraftAttributeInterface $draftAttribute, + ProductAttributeInterface $productAttribute, + VendorInterface $vendor + ): void { + $draftAttribute->getVendor()->willReturn($vendor); + $vendor->getId()->willReturn(1); + $draftAttribute->isTranslatable()->willReturn(true); + $draftAttribute->getStorageType()->willReturn('text'); + $draftAttribute->getConfiguration()->willReturn(['min' => 2, 'max' => 4]); + $draftAttribute->getCode()->willReturn('code'); + $draftAttribute->getType()->willReturn('text'); + $draftAttribute->getPosition()->willReturn(2); + + $productAttribute = $this->createClone($draftAttribute); + + $productAttribute->isTranslatable()->shouldBe(true); + $productAttribute->getStorageType()->shouldBe('text'); + $productAttribute->getCode()->shouldBe('code-1'); + } +} diff --git a/OpenMarketplace/spec/Component/Product/Factory/ProductAttributeValueFactorySpec.php b/OpenMarketplace/spec/Component/Product/Factory/ProductAttributeValueFactorySpec.php new file mode 100644 index 0000000..d42f768 --- /dev/null +++ b/OpenMarketplace/spec/Component/Product/Factory/ProductAttributeValueFactorySpec.php @@ -0,0 +1,35 @@ +beConstructedWith(ProductAttributeValue::class); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(ProductAttributeValueFactoryInterface::class); + } + + public function it_returns_valid_object(): void + { + $this->create()->shouldBeAnInstanceOf(ProductAttributeValueInterface::class); + } +} diff --git a/OpenMarketplace/spec/Component/Product/Factory/ProductVariantTranslationFactorySpec.php b/OpenMarketplace/spec/Component/Product/Factory/ProductVariantTranslationFactorySpec.php new file mode 100644 index 0000000..f078052 --- /dev/null +++ b/OpenMarketplace/spec/Component/Product/Factory/ProductVariantTranslationFactorySpec.php @@ -0,0 +1,63 @@ +shouldHaveType(ProductVariantTranslationFactory::class); + } + + public function it_should_implement_interface(): void + { + $this->shouldImplement(ProductVariantTranslationFactoryInterface::class); + } + + public function it_should_create_empty_product_variant_translation(): void + { + $this->createNew()->shouldHaveType(ProductVariantTranslation::class); + } + + public function it_should_create_product_variant_translation_with_data( + ProductVariantInterface $productVariant + ): void { + $translation = $this->create($productVariant, 'translation', 'en'); + $translation->getName()->shouldReturn('translation'); + $translation->getLocale()->shouldReturn('en'); + $translation->getTranslatable()->shouldReturn($productVariant); + } + + public function it_should_create_product_variant_translation_from_product_listing( + ProductVariantInterface $productVariant, + DraftTranslationInterface $productTranslation + ): void { + $productTranslation->getName()->willReturn('translation'); + $productTranslation->getLocale()->willReturn('en'); + + $productVariantTranslation = $this->createFromProductListingTranslation( + $productVariant, + $productTranslation + ); + + $productVariantTranslation->getName()->shouldReturn('translation'); + $productVariantTranslation->getLocale()->shouldReturn('en'); + $productVariantTranslation->getTranslatable()->shouldReturn($productVariant); + } +} diff --git a/OpenMarketplace/spec/Component/ProductListing/DraftConverter/Cloner/AttributeTranslationClonerSpec.php b/OpenMarketplace/spec/Component/ProductListing/DraftConverter/Cloner/AttributeTranslationClonerSpec.php new file mode 100644 index 0000000..7890f55 --- /dev/null +++ b/OpenMarketplace/spec/Component/ProductListing/DraftConverter/Cloner/AttributeTranslationClonerSpec.php @@ -0,0 +1,61 @@ +beConstructedWith($entityManager, $attributeTranslationFactory); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(AttributeTranslationCloner::class); + } + + public function it_clones_translation( + EntityManagerInterface $entityManager, + ProductAttributeTranslationFactoryInterface $attributeTranslationFactory, + DraftAttributeInterface $draftAttribute, + ProductAttributeInterface $productAttribute, + DraftAttributeTranslationInterface $draftAttributeTranslation, + ProductAttributeTranslationInterface $newProductAttributeTranslation + ): void { + $draftAttributeCollection = new ArrayCollection([$draftAttributeTranslation->getWrappedObject()]); + + $draftAttribute->getTranslations()->willReturn($draftAttributeCollection); + $draftAttributeTranslation->getLocale()->willReturn('pl_PL'); + $draftAttributeTranslation->getName()->willReturn('name'); + $draftAttribute->getProductAttribute()->willReturn($productAttribute); + + $attributeTranslationFactory->create()->willReturn($newProductAttributeTranslation); + + $this->clone($draftAttribute); + + $newProductAttributeTranslation->setLocale('pl_PL')->shouldHaveBeenCalledOnce(); + $newProductAttributeTranslation->setName('name')->shouldHaveBeenCalledOnce(); + $newProductAttributeTranslation->setTranslatable($productAttribute)->shouldHaveBeenCalledOnce(); + } +} diff --git a/OpenMarketplace/spec/Component/ProductListing/DraftConverter/Cloner/AttributeValueClonerSpec.php b/OpenMarketplace/spec/Component/ProductListing/DraftConverter/Cloner/AttributeValueClonerSpec.php new file mode 100644 index 0000000..592352b --- /dev/null +++ b/OpenMarketplace/spec/Component/ProductListing/DraftConverter/Cloner/AttributeValueClonerSpec.php @@ -0,0 +1,68 @@ +beConstructedWith($entityManager, $attributeValueFactory); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(AttributeValueCloner::class); + } + + public function it_clones_attribute_values( + DraftInterface $productDraft, + ProductInterface $product, + DraftAttributeValueInterface $firstAttribute, + DraftAttributeInterface $draftAttribute, + ProductAttributeInterface $productAttribute, + ProductAttributeValueInterface $newProductAttributeValue, + EntityManagerInterface $entityManager, + ProductAttributeValueFactoryInterface $attributeValueFactory + ): void { + $firstAttribute->getAttribute()->willReturn($draftAttribute); + $firstAttribute->getLocaleCode()->willReturn('pl_PL'); + $firstAttribute->getValue()->willReturn('name'); + + $draftAttributeCollection = new ArrayCollection([$firstAttribute->getWrappedObject()]); + $productDraft->getAttributes()->willReturn($draftAttributeCollection); + + $attributeValueFactory->create()->willReturn($newProductAttributeValue); + $draftAttribute->getProductAttribute()->willReturn($productAttribute); + + $this->clone($productDraft, $product); + + $newProductAttributeValue->setSubject($product)->shouldHaveBeenCalledOnce(); + $newProductAttributeValue->setAttribute($productAttribute)->shouldHaveBeenCalledOnce(); + $newProductAttributeValue->setLocaleCode('pl_PL')->shouldHaveBeenCalledOnce(); + $newProductAttributeValue->setValue('name')->shouldHaveBeenCalledOnce(); + $entityManager->persist($newProductAttributeValue)->shouldHaveBeenCalledOnce(); + } +} diff --git a/OpenMarketplace/spec/Component/ProductListing/DraftConverter/Operator/AttributesOperatorSpec.php b/OpenMarketplace/spec/Component/ProductListing/DraftConverter/Operator/AttributesOperatorSpec.php new file mode 100644 index 0000000..4d40c41 --- /dev/null +++ b/OpenMarketplace/spec/Component/ProductListing/DraftConverter/Operator/AttributesOperatorSpec.php @@ -0,0 +1,111 @@ +beConstructedWith( + $productAttributeFactory, + $entityManager, + $attributesExtractor, + $attributeTranslationCloner, + $attributeValueCloner + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(AttributesOperator::class); + } + + public function it_doesnt_link_draft_to_product_attribute_when_it_is_already_linked( + DraftInterface $productDraft, + AttributeValueClonerInterface $attributeValueCloner, + EntityManagerInterface $entityManager, + DraftAttributeInterface $draftAttribute, + DraftAttributeValueInterface $draftAttributeValue, + ProductInterface $product, + ProductAttributeInterface $productAttribute, + DraftAttributesExtractorInterface $attributesExtractor, + ) { + $draftAttributesCollection = new ArrayCollection([$draftAttributeValue->getWrappedObject()]); + $productDraft->getAttributes()->willReturn($draftAttributesCollection); + + $product->getAttributes()->willReturn(new ArrayCollection([])); + + $attributesExtractor->extract($draftAttributesCollection)->willReturn([$draftAttribute]); + + $draftAttribute->getProductAttribute()->willReturn($productAttribute); + + $this->convert($productDraft, $product); + + $entityManager->persist(Argument::any())->shouldNotHaveBeenCalled(); + + $attributeValueCloner->clone($productDraft, $product)->shouldHaveBeenCalledOnce(); + } + + public function it_links_draft_with_product_attribute( + DraftInterface $productDraft, + ProductAttributeFactoryInterface $productAttributeFactory, + AttributeValueClonerInterface $attributeValueCloner, + EntityManagerInterface $entityManager, + DraftAttributeInterface $draftAttribute, + DraftAttributeValueInterface $draftAttributeValue, + ProductInterface $product, + ProductAttributeInterface $productAttribute, + ProductAttributeInterface $newProductAttribute, + DraftAttributesExtractorInterface $attributesExtractor, + AttributeTranslationClonerInterface $attributeTranslationCloner + ) { + $draftAttributesCollection = new ArrayCollection([$draftAttributeValue->getWrappedObject()]); + $productDraft->getAttributes()->willReturn($draftAttributesCollection); + + $product->getAttributes()->willReturn(new ArrayCollection([])); + + $attributesExtractor->extract($draftAttributesCollection)->willReturn([$draftAttribute]); + + $draftAttribute->getProductAttribute()->willReturn(null); + + $productAttributeFactory->createClone($draftAttribute)->willReturn($newProductAttribute); + + $draftAttribute->setProductAttribute($newProductAttribute)->shouldBeCalledOnce(); + $entityManager->persist($newProductAttribute)->shouldBeCalledOnce(); + $entityManager->flush()->shouldBeCalledOnce(); + $attributeTranslationCloner->clone($draftAttribute)->shouldBeCalledOnce(); + + $this->convert($productDraft, $product); + + $attributeValueCloner->clone($productDraft, $product)->shouldHaveBeenCalledOnce(); + } +} diff --git a/OpenMarketplace/spec/Component/ProductListing/DraftConverter/Operator/TaxonsOperatorSpec.php b/OpenMarketplace/spec/Component/ProductListing/DraftConverter/Operator/TaxonsOperatorSpec.php new file mode 100644 index 0000000..07d6412 --- /dev/null +++ b/OpenMarketplace/spec/Component/ProductListing/DraftConverter/Operator/TaxonsOperatorSpec.php @@ -0,0 +1,103 @@ +beConstructedWith( + $entityManager, + $productTaxonFactory + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(TaxonsOperator::class); + } + + public function it_implements_interface(): void + { + $this->shouldImplement(TaxonsOperatorInterface::class); + } + + public function it_copies_non_existing_taxons_from_draft_to_product( + DraftInterface $productDraft, + ProductInterface $product, + TaxonInterface $taxon, + DraftTaxonInterface $productDraftTaxon, + ProductTaxonInterface $productTaxon, + FactoryInterface $productTaxonFactory + ) { + $productDraft->getMainTaxon()->willReturn($taxon); + + $product->getProductTaxons()->willReturn(new ArrayCollection([])); + $productDraft->getProductDraftTaxons()->willReturn(new ArrayCollection([$productDraftTaxon->getWrappedObject()])); + $productDraftTaxon->getTaxon()->willReturn($taxon); + $productDraftTaxon->getProductDraft()->willReturn($productDraft); + $taxon->getId()->willReturn(1); + $productTaxonFactory->createNew()->willReturn($productTaxon); + $productTaxon->getProduct()->willReturn(null); + $productTaxon->getTaxon()->willReturn(null); + + $this->copyTaxonsToProduct($productDraft, $product); + + $productTaxon->setProduct($product)->shouldHaveBeenCalled(); + $productTaxon->setTaxon($taxon)->shouldHaveBeenCalled(); + $product->addProductTaxon($productTaxon)->shouldHaveBeenCalled(); + $product->setMainTaxon($taxon)->shouldHaveBeenCalled(); + } + + public function it_do_not_copy_existing_taxons_from_draft_to_product( + DraftInterface $productDraft, + ProductInterface $product, + TaxonInterface $taxon, + DraftTaxonInterface $productDraftTaxon, + ProductTaxonInterface $productTaxon, + FactoryInterface $productTaxonFactory + ) { + $productDraft->getMainTaxon()->willReturn($taxon); + + $product->getProductTaxons()->willReturn(new ArrayCollection([$productTaxon->getWrappedObject()])); + $productTaxon->getTaxon()->willReturn($taxon); + $productTaxon->getProduct()->willReturn($product); + + $productDraft->getProductDraftTaxons()->willReturn(new ArrayCollection([$productDraftTaxon->getWrappedObject()])); + $productDraftTaxon->getTaxon()->willReturn($taxon); + $productDraftTaxon->getProductDraft()->willReturn($productDraft); + + $taxon->getId()->willReturn(1); + $productTaxonFactory->createNew()->willReturn($productTaxon); + + $this->copyTaxonsToProduct($productDraft, $product); + + $productTaxon->setProduct($product)->shouldNotBeCalled(); + $productTaxon->setTaxon($taxon)->shouldNotBeCalled(); + $product->addProductTaxon($productTaxon)->shouldNotBeCalled(); + $product->setMainTaxon($taxon)->shouldHaveBeenCalled(); + } +} diff --git a/OpenMarketplace/spec/Component/ProductListing/DraftConverter/Updater/ProductAttributeUpdaterSpec.php b/OpenMarketplace/spec/Component/ProductListing/DraftConverter/Updater/ProductAttributeUpdaterSpec.php new file mode 100644 index 0000000..5f9a567 --- /dev/null +++ b/OpenMarketplace/spec/Component/ProductListing/DraftConverter/Updater/ProductAttributeUpdaterSpec.php @@ -0,0 +1,128 @@ +beConstructedWith($entityManager, $attributeTranslationCloner, $attributeTranslationFactory); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(ProductAttributeUpdater::class); + } + + public function it_doesent_clean_translation_when_product_doesnt_have_them( + DraftAttributeInterface $draftAttribute, + EntityManagerInterface $entityManager, + ProductAttributeInterface $productAttribute, + ProductAttributeTranslationInterface $productAttributeTranslation, + DraftAttributeTranslationInterface $draftAttributeTranslation, + ProductAttributeTranslationFactoryInterface $attributeTranslationFactory, + ): void { + $productPosition = 5; + $draftAttributeTranslationCollection = new ArrayCollection([$draftAttributeTranslation->getWrappedObject()]); + $productAttributeTranslationCollection = new ArrayCollection([]); + + $productAttribute->getPosition()->willReturn($productPosition); + $draftAttribute->getTranslations()->willReturn($draftAttributeTranslationCollection); + $productAttribute->getTranslations()->willReturn($productAttributeTranslationCollection); + + $attributeTranslationFactory->create()->willReturn($productAttributeTranslation); + + $productAttribute->setPosition($productPosition)->shouldBeCalledOnce(); + + $this->update($draftAttribute, $productAttribute); + + $entityManager->flush()->shouldNotBeCalled(); + } + + public function it_cleans_translation_before_appending_new( + DraftAttributeInterface $draftAttribute, + EntityManagerInterface $entityManager, + ProductAttributeInterface $productAttribute, + ProductAttributeTranslationInterface $productAttributeTranslation, + ProductAttributeTranslationInterface $firstProductAttributeTranslation, + ProductAttributeTranslationInterface $secondProductAttributeTranslation, + DraftAttributeTranslationInterface $draftAttributeTranslation, + ProductAttributeTranslationFactoryInterface $attributeTranslationFactory, + ): void { + $productPosition = 5; + $draftAttributeTranslationCollection = new ArrayCollection([$draftAttributeTranslation->getWrappedObject()]); + $productAttributeTranslationCollection = new ArrayCollection([ + $firstProductAttributeTranslation->getWrappedObject(), + $secondProductAttributeTranslation->getWrappedObject(), + ]); + + $productAttribute->getPosition()->willReturn($productPosition); + $draftAttribute->getTranslations()->willReturn($draftAttributeTranslationCollection); + $productAttribute->getTranslations()->willReturn($productAttributeTranslationCollection); + + $attributeTranslationFactory->create()->willReturn($productAttributeTranslation); + + $productAttribute->setPosition($productPosition)->shouldBeCalledOnce(); + + $this->update($draftAttribute, $productAttribute); + + $entityManager->remove($firstProductAttributeTranslation)->shouldHaveBeenCalledOnce(); + $entityManager->remove($secondProductAttributeTranslation)->shouldHaveBeenCalledOnce(); + } + + public function it_updates_translations( + DraftAttributeInterface $draftAttribute, + EntityManagerInterface $entityManager, + ProductAttributeInterface $productAttribute, + ProductAttributeTranslationInterface $productAttributeTranslation, + ProductAttributeTranslationInterface $firstProductAttributeTranslation, + ProductAttributeTranslationInterface $secondProductAttributeTranslation, + DraftAttributeTranslationInterface $draftAttributeTranslation, + ProductAttributeTranslationFactoryInterface $attributeTranslationFactory, + AttributeTranslationClonerInterface $attributeTranslationCloner + ): void { + $productPosition = 5; + $draftAttributeTranslationCollection = new ArrayCollection([$draftAttributeTranslation->getWrappedObject()]); + $productAttributeTranslationCollection = new ArrayCollection([ + $firstProductAttributeTranslation->getWrappedObject(), + $secondProductAttributeTranslation->getWrappedObject(), + ]); + + $draftAttributeTranslation->getLocale()->willReturn('pl_PL'); + $draftAttributeTranslation->getName()->willReturn('name'); + $productAttribute->getPosition()->willReturn($productPosition); + $draftAttribute->getTranslations()->willReturn($draftAttributeTranslationCollection); + $productAttribute->getTranslations()->willReturn($productAttributeTranslationCollection); + + $attributeTranslationFactory->create()->willReturn($productAttributeTranslation); + + $productAttribute->setPosition($productPosition)->shouldBeCalledOnce(); + + $this->update($draftAttribute, $productAttribute); + + $attributeTranslationCloner->clone($draftAttribute)->shouldHaveBeenCalledOnce(); + } +} diff --git a/OpenMarketplace/spec/Component/ProductListing/DraftConverterSpec.php b/OpenMarketplace/spec/Component/ProductListing/DraftConverterSpec.php new file mode 100644 index 0000000..b16c00b --- /dev/null +++ b/OpenMarketplace/spec/Component/ProductListing/DraftConverterSpec.php @@ -0,0 +1,161 @@ +beConstructedWith( + $productFromDraftFactory, + $productFromDraftUpdater, + $filesOperator, + $attributesConverter, + $productDraftTaxonsOperator + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(DraftConverter::class); + } + + public function it_implements_interface(): void + { + $this->shouldImplement(DraftConverterInterface::class); + } + + public function it_creates_new_product( + DraftInterface $productDraft, + SimpleProductFactoryInterface $productFromDraftFactory, + ListingInterface $productListing, + TaxonsOperatorInterface $productDraftTaxonsOperator, + ProductInterface $product + ): void { + $productDraft->getProductListing() + ->willReturn($productListing); + + $productListing->getProduct() + ->willReturn(null); + + $productListing->accept() + ->shouldBeCalledOnce(); + + $productFromDraftFactory->create($productDraft) + ->willReturn($product); + + $productDraftTaxonsOperator->copyTaxonsToProduct($productDraft, $product) + ->shouldBeCalled(); + + $this->convertToSimpleProduct($productDraft); + } + + public function it_updates_existing_product( + DraftInterface $productDraft, + SimpleProductUpdaterInterface $productFromDraftUpdater, + ImagesOperatorInterface $filesOperator, + ListingInterface $productListing, + ProductInterface $product, + ProductInterface $updatedProduct, + TaxonsOperatorInterface $productDraftTaxonsOperator + ): void { + $productDraft->getProductListing() + ->willReturn($productListing); + + $productListing->getProduct() + ->willReturn($product); + + $productListing->accept() + ->shouldBeCalledOnce(); + + $productFromDraftUpdater->update($productDraft) + ->willReturn($updatedProduct); + + $filesOperator->removeOldFiles($updatedProduct)->shouldBeCalledTimes(1); + $filesOperator->copyFilesToProduct($productDraft, $updatedProduct)->shouldBeCalledTimes(1); + + $productDraftTaxonsOperator->updateTaxonsInProduct($productDraft, $updatedProduct) + ->shouldBeCalled(); + + $this->convertToSimpleProduct($productDraft); + } + + public function it_converts_attributes_to_existing_product( + DraftInterface $productDraft, + SimpleProductUpdaterInterface $productFromDraftUpdater, + ImagesOperatorInterface $filesOperator, + ListingInterface $productListing, + ProductInterface $product, + ProductInterface $updatedProduct, + AttributesOperatorInterface $attributesConverter + ): void { + $productDraft->getProductListing() + ->willReturn($productListing); + + $productListing->getProduct() + ->willReturn($product); + + $productListing->accept() + ->shouldBeCalledOnce(); + + $productFromDraftUpdater->update($productDraft) + ->willReturn($updatedProduct); + + $filesOperator->removeOldFiles($updatedProduct)->shouldBeCalledTimes(1); + $filesOperator->copyFilesToProduct($productDraft, $updatedProduct)->shouldBeCalledTimes(1); + + $attributesConverter->convert($productDraft, $updatedProduct); + $this->convertToSimpleProduct($productDraft); + } + + public function it_converts_attributes_to_new_product( + DraftInterface $productDraft, + SimpleProductUpdaterInterface $productFromDraftUpdater, + SimpleProductFactoryInterface $productFromDraftFactory, + ListingInterface $productListing, + ProductInterface $newProduct, + AttributesOperatorInterface $attributesConverter + ): void { + $productDraft->getProductListing() + ->willReturn($productListing); + + $productListing->getProduct() + ->willReturn(null); + + $productListing->accept() + ->shouldBeCalledOnce(); + + $productFromDraftUpdater->update($productDraft) + ->willReturn(null); + + $productFromDraftFactory->create($productDraft)->willReturn($newProduct); + $attributesConverter->convert($productDraft, $newProduct); + $this->convertToSimpleProduct($productDraft); + } +} diff --git a/OpenMarketplace/spec/Component/ProductListing/DraftGenerator/Cloner/DraftPricingClonerSpec.php b/OpenMarketplace/spec/Component/ProductListing/DraftGenerator/Cloner/DraftPricingClonerSpec.php new file mode 100644 index 0000000..a422509 --- /dev/null +++ b/OpenMarketplace/spec/Component/ProductListing/DraftGenerator/Cloner/DraftPricingClonerSpec.php @@ -0,0 +1,85 @@ +beConstructedWith($priceFactory); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(DraftPricingCloner::class); + } + + public function it_implements_interface(): void + { + $this->shouldImplement(DraftPricingClonerInterface::class); + } + + public function it_clones_product_listing_prices( + DraftPricingFactoryInterface $priceFactory, + DraftInterface $newProductDraft, + DraftInterface $productDraft, + ListingPriceInterface $price, + ListingPriceInterface $newPrice, + ): void { + $productDraft->getProductListingPrices() + ->willReturn(new ArrayCollection([$price->getWrappedObject()])); + + $price->getProductDraft() + ->willReturn($productDraft); + + $price->getChannelCode() + ->willReturn('en_US'); + + $priceFactory->createForChannelCode( + 'en_US', + $productDraft + )->willReturn($newPrice); + + $price->getPrice() + ->willReturn(1000); + + $price->getMinimumPrice() + ->willReturn(1000); + + $price->getOriginalPrice() + ->willReturn(1000); + + $newPrice->setPrice(1000) + ->shouldBeCalled(); + + $newPrice->setMinimumPrice(1000) + ->shouldBeCalled(); + + $newPrice->setOriginalPrice(1000) + ->shouldBeCalled(); + + $newPrice->getChannelCode() + ->willReturn('en_US'); + + $newProductDraft->addProductListingPriceWithKey($newPrice, 'en_US'); + + $this->clone($productDraft, $newProductDraft); + } +} diff --git a/OpenMarketplace/spec/Component/ProductListing/DraftGenerator/Cloner/DraftTranslationClonerSpec.php b/OpenMarketplace/spec/Component/ProductListing/DraftGenerator/Cloner/DraftTranslationClonerSpec.php new file mode 100644 index 0000000..57146a8 --- /dev/null +++ b/OpenMarketplace/spec/Component/ProductListing/DraftGenerator/Cloner/DraftTranslationClonerSpec.php @@ -0,0 +1,102 @@ +beConstructedWith($translationFactory); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(DraftTranslationCloner::class); + } + + public function it_implements_interface(): void + { + $this->shouldImplement(DraftTranslationClonerInterface::class); + } + + public function it_clones_product_listing_translations( + DraftInterface $newProductDraft, + DraftInterface $productDraft, + DraftTranslationInterface $translation, + DraftTranslationInterface $newTranslation, + FactoryInterface $translationFactory + ): void { + $productDraft->getTranslations() + ->willReturn(new ArrayCollection([$translation->getWrappedObject()])); + + $translation->getLocale() + ->willReturn('en_US'); + + $translationFactory->createNew() + ->willReturn($newTranslation); + + $translation->getName() + ->willReturn('name'); + + $translation->getDescription() + ->willReturn('description'); + + $translation->getMetaDescription() + ->willReturn('metaDescription'); + + $translation->getMetaKeywords() + ->willReturn('metaKeywords'); + + $translation->getSlug() + ->willReturn('slug'); + + $translation->getShortDescription() + ->willReturn('shortDescription'); + + $newTranslation->setName('name') + ->shouldBeCalled(); + + $newTranslation->setProductDraft($newProductDraft) + ->shouldBeCalled(); + + $newTranslation->setDescription('description') + ->shouldBeCalled(); + + $newTranslation->setLocale('en_US') + ->shouldBeCalled(); + + $newTranslation->setMetaDescription('metaDescription') + ->shouldBeCalled(); + + $newTranslation->setMetaKeywords('metaKeywords') + ->shouldBeCalled(); + + $newTranslation->setSlug('slug') + ->shouldBeCalled(); + + $newTranslation->setShortDescription('shortDescription') + ->shouldBeCalled(); + + $newProductDraft->addTranslationWithKey($newTranslation, 'en_US') + ->shouldBeCalled(); + + $this->clone($productDraft, $newProductDraft); + } +} diff --git a/OpenMarketplace/spec/Component/ProductListing/DraftGenerator/Factory/DraftAttributeFactorySpec.php b/OpenMarketplace/spec/Component/ProductListing/DraftGenerator/Factory/DraftAttributeFactorySpec.php new file mode 100644 index 0000000..088e8e5 --- /dev/null +++ b/OpenMarketplace/spec/Component/ProductListing/DraftGenerator/Factory/DraftAttributeFactorySpec.php @@ -0,0 +1,63 @@ +beConstructedWith($factory, $attributeTypesRegistry, $vendorProvider); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(DraftAttributeFactory::class); + } + + public function it_creates_typed_attribute( + ServiceRegistryInterface $attributeTypesRegistry, + AttributeTypeInterface $attributeType, + VendorContextInterface $vendorProvider, + FactoryInterface $factory, + DraftAttributeInterface $attribute, + DraftAttributeInterface $typedAttribute, + VendorInterface $vendor + ): void { + $type = 'text'; + $storageType = 'text'; + + $attributeTypesRegistry->get($type)->willReturn($attributeType); + $attributeType->getStorageType()->willReturn($storageType); + $factory->createNew()->willReturn($attribute); + $vendorProvider->getVendor()->willReturn($vendor); + + $attribute->setType($type)->shouldBeCalledOnce(); + $attribute->setStorageType($storageType)->shouldBeCalledOnce(); + $attribute->setVendor($vendor)->shouldBeCalledOnce(); + + $item = $this->createTyped($type, $vendor); + + $item->shouldBeAnInstanceOf(DraftAttributeInterface::class); + } +} diff --git a/OpenMarketplace/spec/Component/ProductListing/DraftGenerator/Factory/DraftImageFactorySpec.php b/OpenMarketplace/spec/Component/ProductListing/DraftGenerator/Factory/DraftImageFactorySpec.php new file mode 100644 index 0000000..d05090b --- /dev/null +++ b/OpenMarketplace/spec/Component/ProductListing/DraftGenerator/Factory/DraftImageFactorySpec.php @@ -0,0 +1,30 @@ +shouldHaveType(DraftImageFactory::class); + } + + public function it_creates_valid_image(): void + { + $image = $this->createNew(); + $image->shouldBeAnInstanceOf(DraftImageInterface::class); + } +} diff --git a/OpenMarketplace/spec/Component/ProductListing/Entity/DraftSpec.php b/OpenMarketplace/spec/Component/ProductListing/Entity/DraftSpec.php new file mode 100644 index 0000000..dda2647 --- /dev/null +++ b/OpenMarketplace/spec/Component/ProductListing/Entity/DraftSpec.php @@ -0,0 +1,242 @@ +shouldHaveType(Draft::class); + } + + public function it_returns_id(): void + { + $this->setId(1); + $this->getId()->shouldBeInt(); + } + + public function it_returns_translation(): void + { + $this->getTranslations()->shouldBeAnInstanceOf(ArrayCollection::class); + } + + public function it_returns_image(): void + { + $this->getImages()->shouldBeAnInstanceOf(ArrayCollection::class); + } + + public function it_gets_attribute_by_locale( + DraftAttributeValueInterface $attributeValuePL, + DraftAttributeValueInterface $attributeValueEN, + DraftAttributeInterface $attribute, + ): void { + $attribute->getCode()->willReturn('colour'); + + $attributeValuePL->setDraft($this)->shouldBeCalled(); + $attributeValuePL->getLocaleCode()->willReturn('pl_PL'); + $attributeValuePL->getAttribute()->willReturn($attribute); + $attributeValuePL->getCode()->willReturn('colour'); + $attributeValuePL->getValue()->willReturn('Niebieski'); + + $attributeValueEN->setDraft($this)->shouldBeCalled(); + $attributeValueEN->getLocaleCode()->willReturn('en_US'); + $attributeValueEN->getAttribute()->willReturn($attribute); + $attributeValueEN->getCode()->willReturn('colour'); + $attributeValueEN->getValue()->willReturn('Blue'); + + $this->addAttribute($attributeValuePL); + $this->addAttribute($attributeValueEN); + + $this->getAttributesByLocale('pl_PL', 'en_US')->shouldIterateAs([$attributeValuePL->getWrappedObject()]); + } + + public function it_returns_attributes_by_a_fallback_locale_when_there_is_no_value_for_a_given_locale( + DraftAttributeInterface $attribute, + DraftAttributeValueInterface $attributeValueEN, + ): void { + $attribute->getCode()->willReturn('colour'); + + $attributeValueEN->setDraft($this)->shouldBeCalled(); + $attributeValueEN->getLocaleCode()->willReturn('en_US'); + $attributeValueEN->getAttribute()->willReturn($attribute); + $attributeValueEN->getCode()->willReturn('colour'); + $attributeValueEN->getValue()->willReturn('Blue'); + + $this->addAttribute($attributeValueEN); + + $this + ->getAttributesByLocale('pl_PL', 'en_US') + ->shouldIterateAs([$attributeValueEN->getWrappedObject()]) + ; + } + + public function it_returns_attributes_by_a_fallback_locale_when_there_is_an_empty_value_for_a_given_locale( + DraftAttributeInterface $attribute, + DraftAttributeValueInterface $attributeValueEN, + DraftAttributeValueInterface $attributeValuePL, + ): void { + $attribute->getCode()->willReturn('colour'); + + $attributeValueEN->setDraft($this)->shouldBeCalled(); + $attributeValueEN->getLocaleCode()->willReturn('en_US'); + $attributeValueEN->getAttribute()->willReturn($attribute); + $attributeValueEN->getCode()->willReturn('colour'); + $attributeValueEN->getValue()->willReturn('Blue'); + + $attributeValuePL->setDraft($this)->shouldBeCalled(); + $attributeValuePL->getLocaleCode()->willReturn('pl_PL'); + $attributeValuePL->getAttribute()->willReturn($attribute); + $attributeValuePL->getCode()->willReturn('colour'); + $attributeValuePL->getValue()->willReturn(''); + + $this->addAttribute($attributeValueEN); + $this->addAttribute($attributeValuePL); + + $this + ->getAttributesByLocale('pl_PL', 'en_US') + ->shouldIterateAs([$attributeValueEN->getWrappedObject()]) + ; + } + + public function it_removes_attribute(DraftAttributeValueInterface $attribute): void + { + $attribute->setDraft($this)->shouldBeCalled(); + + $this->addAttribute($attribute); + $this->hasAttribute($attribute)->shouldReturn(true); + + $attribute->setDraft(null)->shouldBeCalled(); + + $this->removeAttribute($attribute); + $this->hasAttribute($attribute)->shouldReturn(false); + } + + public function it_has_no_id_by_default(): void + { + $this->getId()->shouldReturn(null); + } + + public function it_initializes_attribute_collection_by_default(): void + { + $this->getAttributes()->shouldHaveType(Collection::class); + } + + public function it_adds_attribute(DraftAttributeValueInterface $attribute): void + { + $attribute->setDraft($this)->shouldBeCalled(); + + $this->addAttribute($attribute); + $this->hasAttribute($attribute)->shouldReturn(true); + } + + public function it_returns_attributes_by_a_locale_without_a_base_locale( + DraftAttributeInterface $attribute, + DraftAttributeValueInterface $attributeValueEN, + DraftAttributeValueInterface $attributeValuePL, + ): void { + $attribute->getCode()->willReturn('colour'); + + $attributeValueEN->setDraft($this)->shouldBeCalled(); + $attributeValueEN->getLocaleCode()->willReturn('en_US'); + $attributeValueEN->getAttribute()->willReturn($attribute); + $attributeValueEN->getCode()->willReturn('colour'); + $attributeValueEN->getValue()->willReturn('Blue'); + + $attributeValuePL->setDraft($this)->shouldBeCalled(); + $attributeValuePL->getLocaleCode()->willReturn('pl_PL'); + $attributeValuePL->getAttribute()->willReturn($attribute); + $attributeValuePL->getCode()->willReturn('colour'); + $attributeValuePL->getValue()->willReturn('Niebieski'); + + $this->addAttribute($attributeValueEN); + $this->addAttribute($attributeValuePL); + + $this + ->getAttributesByLocale('pl_PL', 'en_US') + ->shouldIterateAs([$attributeValuePL->getWrappedObject()]) + ; + } + + public function it_returns_attributes_by_a_base_locale_when_there_is_no_value_for_a_given_locale_or_a_fallback_locale( + DraftAttributeInterface $attribute, + DraftAttributeValueInterface $attributeValueFR, + ): void { + $attribute->getCode()->willReturn('colour'); + + $attributeValueFR->setDraft($this)->shouldBeCalled(); + $attributeValueFR->getLocaleCode()->willReturn('fr_FR'); + $attributeValueFR->getAttribute()->willReturn($attribute); + $attributeValueFR->getCode()->willReturn('colour'); + $attributeValueFR->getValue()->willReturn('Bleu'); + + $this->addAttribute($attributeValueFR); + + $this + ->getAttributesByLocale('pl_PL', 'en_US', 'fr_FR') + ->shouldIterateAs([$attributeValueFR->getWrappedObject()]) + ; + } + + public function it_returns_attributes_by_a_base_locale_when_there_is_an_empty_value_for_a_given_locale_or_a_fallback_locale( + DraftAttributeInterface $attribute, + DraftAttributeValueInterface $attributeValueEN, + DraftAttributeValueInterface $attributeValuePL, + DraftAttributeValueInterface $attributeValueFR, + ): void { + $attribute->getCode()->willReturn('colour'); + + $attributeValueEN->setDraft($this)->shouldBeCalled(); + $attributeValueEN->getLocaleCode()->willReturn('en_US'); + $attributeValueEN->getAttribute()->willReturn($attribute); + $attributeValueEN->getCode()->willReturn('colour'); + $attributeValueEN->getValue()->willReturn(''); + + $attributeValuePL->setDraft($this)->shouldBeCalled(); + $attributeValuePL->getLocaleCode()->willReturn('pl_PL'); + $attributeValuePL->getAttribute()->willReturn($attribute); + $attributeValuePL->getCode()->willReturn('colour'); + $attributeValuePL->getValue()->willReturn(null); + + $attributeValueFR->setDraft($this)->shouldBeCalled(); + $attributeValueFR->getLocaleCode()->willReturn('fr_FR'); + $attributeValueFR->getAttribute()->willReturn($attribute); + $attributeValueFR->getCode()->willReturn('colour'); + $attributeValueFR->getValue()->willReturn('Bleu'); + + $this->addAttribute($attributeValueEN); + $this->addAttribute($attributeValuePL); + $this->addAttribute($attributeValueFR); + + $this + ->getAttributesByLocale('pl_PL', 'en_US', 'fr_FR') + ->shouldIterateAs([$attributeValueFR->getWrappedObject()]) + ; + } + + public function it_initializes_creation_date_by_default(): void + { + $this->getCreatedAt()->shouldHaveType(\DateTimeInterface::class); + } + + public function its_creation_date_is_mutable(\DateTime $creationDate): void + { + $this->setCreatedAt($creationDate); + $this->getCreatedAt()->shouldReturn($creationDate); + } +} diff --git a/OpenMarketplace/spec/Component/ProductListing/Validator/ProductListingPriceValidatorSpec.php b/OpenMarketplace/spec/Component/ProductListing/Validator/ProductListingPriceValidatorSpec.php new file mode 100644 index 0000000..f31e4c1 --- /dev/null +++ b/OpenMarketplace/spec/Component/ProductListing/Validator/ProductListingPriceValidatorSpec.php @@ -0,0 +1,90 @@ +beConstructedWith($channelRepository); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(ProductListingPriceValidator::class); + $this->shouldImplement(ConstraintValidatorInterface::class); + } + + public function it_throws_an_exception_on_wrong_constraint( + Constraint $constraint, + DraftInterface $productDraft + ): void { + $this + ->shouldThrow(UnexpectedTypeException::class) + ->during('validate', [$productDraft, $constraint]); + } + + public function it_adds_violation_if_no_product_listing_price_provided( + ExecutionContextInterface $executionContext, + ChannelRepositoryInterface $channelRepository, + ChannelInterface $channel, + DraftInterface $productDraft, + ListingPriceInterface $productListingPrice + ): void { + $constraint = new ProductListingPriceConstraint(); + + $this->initialize($executionContext); + + $channelRepository->findAll()->willReturn(new ArrayCollection([$channel->getWrappedObject()])); + $productDraft->getProductListingPriceForChannel($channel)->willReturn($productListingPrice); + $productListingPrice->getPrice()->willReturn(null); + + $this->validate($productDraft, $constraint); + + $executionContext->addViolation($constraint->message) + ->shouldBeCalled(); + } + + public function it_does_not_add_violation_if_product_listing_price_provided( + ExecutionContextInterface $executionContext, + ChannelRepositoryInterface $channelRepository, + ChannelInterface $channel, + DraftInterface $productDraft, + ListingPriceInterface $productListingPrice + ): void { + $constraint = new ProductListingPriceConstraint(); + + $this->initialize($executionContext); + + $channelRepository->findAll()->willReturn(new ArrayCollection([$channel->getWrappedObject()])); + $productDraft->getProductListingPriceForChannel($channel)->willReturn($productListingPrice); + $productListingPrice->getPrice()->willReturn(123); + + $this->validate($productDraft, $constraint); + + $executionContext->addViolation($constraint->message) + ->shouldNotBeCalled(); + } +} diff --git a/OpenMarketplace/spec/Component/ProductListing/Validator/UniqueProductListingSlugValidatorSpec.php b/OpenMarketplace/spec/Component/ProductListing/Validator/UniqueProductListingSlugValidatorSpec.php new file mode 100644 index 0000000..890db9c --- /dev/null +++ b/OpenMarketplace/spec/Component/ProductListing/Validator/UniqueProductListingSlugValidatorSpec.php @@ -0,0 +1,101 @@ +beConstructedWith($productTranslationRepository, $requestStack); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(UniqueProductListingSlugValidator::class); + $this->shouldImplement(ConstraintValidatorInterface::class); + } + + public function it_throws_an_exception_on_wrong_constraint( + Constraint $constraint, + DraftTranslationInterface $existingProductTranslation, + ): void { + $this + ->shouldThrow(UnexpectedTypeException::class) + ->during('validate', [$existingProductTranslation, $constraint]); + } + + public function it_adds_violation_if_creating_new_product_draft_with_taken_slug( + RepositoryInterface $productTranslationRepository, + DraftTranslationInterface $existingProductTranslation, + ExecutionContextInterface $executionContext, + ConstraintViolationBuilderInterface $builder, + RequestStack $requestStack, + Request $request, + ): void { + $constraint = new UniqueProductListingSlugConstraint(); + $this->initialize($executionContext); + + $existingProductTranslation->getSlug()->willReturn('slug'); + $requestStack->getCurrentRequest()->willReturn($request); + $request->get('_route')->willReturn(UniqueProductListingSlugValidator::PRODUCT_LISTING_CREATE_PRODUCT_ROUTE); + $productTranslationRepository->findOneBy(['slug' => 'slug'])->willReturn($existingProductTranslation); + + $builder->atPath('slug')->willReturn($builder); + $builder->setInvalidValue(Argument::any())->willReturn($builder); + $builder->setCode(Argument::any())->willReturn($builder); + $executionContext->buildViolation($constraint->message)->willReturn($builder); + + $this->validate($existingProductTranslation, $constraint); + + $builder->addViolation()->shouldBeCalled(); + } + + public function it_does_not_add_violation_if_slug_not_taken( + RepositoryInterface $productTranslationRepository, + DraftTranslationInterface $existingProductTranslation, + ExecutionContextInterface $executionContext, + ConstraintViolationBuilderInterface $builder, + RequestStack $requestStack, + Request $request, + ): void { + $constraint = new UniqueProductListingSlugConstraint(); + $this->initialize($executionContext); + + $existingProductTranslation->getSlug()->willReturn('slug'); + $requestStack->getCurrentRequest()->willReturn($request); + $request->get('_route')->willReturn(UniqueProductListingSlugValidator::PRODUCT_LISTING_CREATE_PRODUCT_ROUTE); + $productTranslationRepository->findOneBy(['slug' => 'slug'])->willReturn(null); + + $builder->atPath('slug')->willReturn($builder); + $builder->setInvalidValue(Argument::any())->willReturn($builder); + $builder->setCode(Argument::any())->willReturn($builder); + $executionContext->buildViolation($constraint->message)->willReturn($builder); + + $this->validate($existingProductTranslation, $constraint); + + $builder->addViolation()->shouldNotBeCalled(); + } +} diff --git a/OpenMarketplace/spec/Component/Settlement/Creator/SettlementCreatorSpec.php b/OpenMarketplace/spec/Component/Settlement/Creator/SettlementCreatorSpec.php new file mode 100644 index 0000000..999b2dc --- /dev/null +++ b/OpenMarketplace/spec/Component/Settlement/Creator/SettlementCreatorSpec.php @@ -0,0 +1,186 @@ +beConstructedWith( + $settlementRepository, + $orderRepository, + $settlementFactory, + $settlementManager, + $settlementPeriodResolver + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(SettlementCreator::class); + } + + public function it_implements_settlement_creator_interface(): void + { + $this->shouldImplement(SettlementCreatorInterface::class); + } + + public function it_creates_settlements_for_vendor_and_channels( + VendorInterface $vendor, + ChannelInterface $channelA, + ChannelInterface $channelB, + SettlementInterface $settlementB, + SettlementInterface $lastSettlementA, + SettlementRepositoryInterface $settlementRepository, + OrderRepositoryInterface $orderRepository, + SettlementFactoryInterface $settlementFactory, + EntityManagerInterface $settlementManager, + SettlementPeriodResolverInterface $settlementPeriodResolver, + ): void { + $from = new \DateTime('2021-01-01'); + $to = new \DateTime('2021-01-31'); + $lastSettlementAEndDate = new \DateTime('2021-01-15'); + $lastSettlementBEndAt = null; + $totalB = 9481; + $totalCommissionB = 243; + + $channels = [$channelA, $channelB]; + + $vendor->hasCyclicalSettlementFrequency()->willReturn(true); + + $settlementRepository->findLastByVendorAndChannel( + $vendor, + $channelA, + )->willReturn($lastSettlementA); + + $lastSettlementA->getEndDate()->willReturn($lastSettlementAEndDate); + + $settlementPeriodResolver->getSettlementDateRangeForVendor( + $vendor, + true, + $lastSettlementAEndDate + )->willReturn([$from, $to]); + + $orderRepository->findForSettlementByVendorAndChannelAndDates( + $vendor, + $channelA, + $from, + $to + )->shouldNotBeCalled(); + + $settlementRepository->findLastByVendorAndChannel( + $vendor, + $channelB + )->willReturn(null); + + $settlementPeriodResolver->getSettlementDateRangeForVendor( + $vendor, + true, + $lastSettlementBEndAt + )->willReturn([$from, $to]); + + $orderRepository->findForSettlementByVendorAndChannelAndDates( + $vendor, + $channelB, + $from, + $to + )->willReturn([ + 'total' => $totalB, + 'commissionTotal' => $totalCommissionB, + ]); + + $settlementFactory->createNewForVendorAndChannel( + $vendor, + $channelB, + $totalB, + $totalCommissionB, + $from, + $to + )->willReturn($settlementB); + + $settlementManager->persist($settlementB)->shouldBeCalled(); + + $this->createSettlementsForAutoGeneration( + $vendor, + $channels + )->shouldBeLike([ + $settlementB, + ]); + } + + public function it_creates_settlement_for_vendor_and_channel_and_amount( + VendorInterface $vendor, + ChannelInterface $channel, + SettlementInterface $settlement, + SettlementInterface $lastSettlement, + SettlementRepositoryInterface $settlementRepository, + SettlementFactoryInterface $settlementFactory, + EntityManagerInterface $settlementManager, + SettlementPeriodResolverInterface $settlementPeriodResolver, + ): void { + $from = new \DateTime('2021-01-01'); + $to = new \DateTime('2021-01-31'); + $lastSettlementEndDate = new \DateTime('2020-12-29'); + $amount = 9481; + + $vendor->hasCyclicalSettlementFrequency()->willReturn(false); + + $settlementRepository->findLastByVendorAndChannel( + $vendor, + $channel, + )->willReturn($lastSettlement); + + $lastSettlement->getEndDate()->willReturn($lastSettlementEndDate); + + $settlementPeriodResolver->getSettlementDateRangeForVendor( + $vendor, + false, + $lastSettlementEndDate + )->willReturn([$from, $to]); + + $settlementFactory->createNewForVendorAndChannel( + $vendor, + $channel, + $amount, + 0, + $from, + $to + )->willReturn($settlement); + + $settlementManager->persist($settlement)->shouldBeCalled(); + + $this->createSettlementForWithdrawal( + $vendor, + $channel, + $amount + )->shouldBeLike( + $settlement, + ); + } +} diff --git a/OpenMarketplace/spec/Component/Settlement/Creator/VirtualWalletCreatorSpec.php b/OpenMarketplace/spec/Component/Settlement/Creator/VirtualWalletCreatorSpec.php new file mode 100644 index 0000000..1edac16 --- /dev/null +++ b/OpenMarketplace/spec/Component/Settlement/Creator/VirtualWalletCreatorSpec.php @@ -0,0 +1,66 @@ +beConstructedWith($virtualWalletFactory, $virtualWalletRepository); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(VirtualWalletCreator::class); + } + + public function it_implements_virtual_wallet_creator_interface(): void + { + $this->shouldImplement(VirtualWalletCreatorInterface::class); + } + + public function it_creates_virtual_wallet( + VendorInterface $vendor, + ChannelInterface $channel, + VirtualWalletFactoryInterface $virtualWalletFactory, + VirtualWalletRepositoryInterface $virtualWalletRepository + ): void { + $virtualWalletRepository->findByVendorAndChannel($vendor, $channel)->willReturn(null); + $virtualWalletFactory->createForVendorAndChannel($vendor, $channel)->shouldBeCalled(); + + $this->createForVendorAndChannel($vendor, $channel); + } + + public function it_finds_virtual_wallet( + VendorInterface $vendor, + ChannelInterface $channel, + VirtualWalletInterface $virtualWallet, + VirtualWalletFactoryInterface $virtualWalletFactory, + VirtualWalletRepositoryInterface $virtualWalletRepository + ): void { + $virtualWalletRepository->findByVendorAndChannel($vendor, $channel)->willReturn($virtualWallet); + $virtualWalletFactory->createForVendorAndChannel($vendor, $channel)->shouldNotBeCalled(); + + $this->createForVendorAndChannel($vendor, $channel); + } +} diff --git a/OpenMarketplace/spec/Component/Settlement/Entity/VirtualWalletSpec.php b/OpenMarketplace/spec/Component/Settlement/Entity/VirtualWalletSpec.php new file mode 100644 index 0000000..b59b109 --- /dev/null +++ b/OpenMarketplace/spec/Component/Settlement/Entity/VirtualWalletSpec.php @@ -0,0 +1,69 @@ +shouldHaveType(VirtualWallet::class); + } + + public function it_implements_interface(): void + { + $this->shouldImplement(VirtualWalletInterface::class); + } + + public function it_throws_exception_if_balance_not_enough( + SettlementInterface $settlement, + ): void { + $settlement->getTotalProfitAmount()->willReturn(1000); + + $this->getBalance()->shouldBeLike(0); + $this->shouldThrow(NotEnoughFundsException::class)->during('withdraw', [$settlement]); + } + + public function it_stashes_order( + OrderInterface $order, + ): void { + $order->getTotalProfitAmount()->willReturn(500); + $this->getBalance()->shouldBeLike(0); + + $this->stash($order); + $this->getBalance()->shouldBeLike(500); + } + + public function it_withdraws_when_balance_is_enough( + SettlementInterface $settlement, + OrderInterface $order, + ): void { + $order->getTotalProfitAmount()->willReturn(500); + $settlement->getTotalProfitAmount()->willReturn(100); + + $this->getBalance()->shouldBeLike(0); + $this->stash($order); + $this->getBalance()->shouldBeLike(500); + $this->withdraw($settlement); + $this->getBalance()->shouldBeLike(400); + } +} diff --git a/OpenMarketplace/spec/Component/Settlement/Manager/VirtualWalletManagerSpec.php b/OpenMarketplace/spec/Component/Settlement/Manager/VirtualWalletManagerSpec.php new file mode 100644 index 0000000..911e44f --- /dev/null +++ b/OpenMarketplace/spec/Component/Settlement/Manager/VirtualWalletManagerSpec.php @@ -0,0 +1,259 @@ +beConstructedWith( + $virtualWalletCreator, + $entityManager, + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(VirtualWalletManager::class); + } + + public function it_implements_virtual_wallet_manager_interface(): void + { + $this->shouldImplement(VirtualWalletManagerInterface::class); + } + + public function it_does_not_stash_order_if_primary_order( + OrderInterface $order, + VendorInterface $vendor, + ChannelInterface $channel, + VirtualWalletInterface $virtualWallet, + VirtualWalletCreatorInterface $virtualWalletCreator, + EntityManagerInterface $entityManager, + ): void { + $order->getVendor()->willReturn(null); + + $order->getChannel()->shouldNotBeCalled(); + $vendor->getSettlementFrequency()->shouldNotBeCalled(); + $virtualWalletCreator->createForVendorAndChannel($vendor, $channel)->shouldNotBeCalled(); + $virtualWallet->stash($order)->shouldNotBeCalled(); + + $entityManager->persist($virtualWallet)->shouldNotBeCalled(); + + $this->stash($order); + } + + public function it_does_not_stash_order_if_unsupported_frequency( + OrderInterface $order, + VendorInterface $vendor, + ChannelInterface $channel, + VirtualWalletInterface $virtualWallet, + VirtualWalletCreatorInterface $virtualWalletCreator, + EntityManagerInterface $entityManager, + ): void { + $order->getVendor()->willReturn($vendor); + $order->getChannel()->willReturn($channel); + + $vendor->getSettlementFrequency()->willReturn(VendorSettlementFrequency::WEEKLY); + + $virtualWalletCreator->createForVendorAndChannel($vendor, $channel)->shouldNotBeCalled(); + $virtualWallet->stash($order)->shouldNotBeCalled(); + + $entityManager->persist($virtualWallet)->shouldNotBeCalled(); + + $this->stash($order); + } + + public function it_stashes_order( + OrderInterface $order, + VendorInterface $vendor, + ChannelInterface $channel, + VirtualWalletInterface $virtualWallet, + VirtualWalletCreatorInterface $virtualWalletCreator, + EntityManagerInterface $entityManager, + ): void { + $order->getVendor()->willReturn($vendor); + $order->getChannel()->willReturn($channel); + + $vendor->getSettlementFrequency()->willReturn(VendorSettlementFrequency::VIRTUAL_WALLET); + + $virtualWalletCreator->createForVendorAndChannel($vendor, $channel)->willReturn($virtualWallet); + $virtualWallet->stash($order)->shouldBeCalled(); + + $entityManager->persist($virtualWallet)->shouldBeCalled(); + + $this->stash($order); + } + + public function it_withdraws_if_frequency_supports_wallet_operations( + SettlementInterface $settlement, + VendorInterface $vendor, + ChannelInterface $channel, + VirtualWalletInterface $virtualWallet, + VirtualWalletCreatorInterface $virtualWalletCreator, + EntityManagerInterface $entityManager, + ): void { + $settlement->getVendor()->willReturn($vendor); + $settlement->getChannel()->willReturn($channel); + + $vendor->getSettlementFrequency()->willReturn(VendorSettlementFrequency::VIRTUAL_WALLET); + $virtualWalletCreator->createForVendorAndChannel($vendor, $channel)->willReturn($virtualWallet); + $virtualWallet->withdraw($settlement)->shouldBeCalled(); + $entityManager->persist($virtualWallet)->shouldBeCalled(); + + $this->withdraw($settlement); + } + + public function it_does_not_withdraw_for_invalid_change_set( + SettlementInterface $settlement, + VendorInterface $vendor, + ChannelInterface $channel, + VirtualWalletInterface $virtualWallet, + VirtualWalletCreatorInterface $virtualWalletCreator, + EntityManagerInterface $entityManager, + ): void { + $settlement->getVendor()->willReturn($vendor); + $settlement->getChannel()->willReturn($channel); + + $vendor->getSettlementFrequency()->willReturn(VendorSettlementFrequency::WEEKLY); + $virtualWalletCreator->createForVendorAndChannel($vendor, $channel)->willReturn($virtualWallet); + $virtualWallet->withdraw($settlement)->shouldBeCalled(); + $entityManager->persist($virtualWallet)->shouldBeCalled(); + + $eventArgs = new PostUpdateEventArgs( + $settlement->getWrappedObject(), + $entityManager->getWrappedObject(), + ); + + $virtualWalletCreator->createForVendorAndChannel($vendor, $channel)->shouldNotBeCalled(); + $virtualWallet->withdraw($settlement)->shouldNotBeCalled(); + $entityManager->persist($virtualWallet)->shouldNotBeCalled(); + + $this->withdraw($settlement, $eventArgs); + } + + public function it_does_not_withdraw_for_invalid_event_object( + SettlementInterface $settlement, + VendorInterface $vendor, + ChannelInterface $channel, + VirtualWalletInterface $virtualWallet, + VirtualWalletCreatorInterface $virtualWalletCreator, + EntityManagerInterface $entityManager, + ): void { + $settlement->getVendor()->willReturn($vendor); + $settlement->getChannel()->willReturn($channel); + + $vendor->getSettlementFrequency()->willReturn(VendorSettlementFrequency::WEEKLY); + $virtualWalletCreator->createForVendorAndChannel($vendor, $channel)->willReturn($virtualWallet); + $virtualWallet->withdraw($settlement)->shouldBeCalled(); + $entityManager->persist($virtualWallet)->shouldBeCalled(); + + $eventArgs = new PostUpdateEventArgs( + $vendor->getWrappedObject(), + $entityManager->getWrappedObject(), + ); + + $unitOfWork = Mockery::mock(UnitOfWork::class); + $unitOfWork->shouldReceive('getEntityChangeSet')->withArgs([$vendor->getWrappedObject()])->andReturn(['foo' => ['bar', 'baz']]); + $entityManager->getUnitOfWork()->willReturn($unitOfWork); + + $virtualWalletCreator->createForVendorAndChannel($vendor, $channel)->shouldNotBeCalled(); + $virtualWallet->withdraw($settlement)->shouldNotBeCalled(); + $entityManager->persist($virtualWallet)->shouldNotBeCalled(); + + $this->withdraw($settlement, $eventArgs); + } + + public function it_does_not_withdraw_for_invalid_previous_frequency( + SettlementInterface $settlement, + VendorInterface $vendor, + ChannelInterface $channel, + VirtualWalletInterface $virtualWallet, + VirtualWalletCreatorInterface $virtualWalletCreator, + EntityManagerInterface $entityManager, + ): void { + $settlement->getVendor()->willReturn($vendor); + $settlement->getChannel()->willReturn($channel); + + $vendor->getSettlementFrequency()->willReturn(VendorSettlementFrequency::WEEKLY); + $virtualWalletCreator->createForVendorAndChannel($vendor, $channel)->willReturn($virtualWallet); + $virtualWallet->withdraw($settlement)->shouldBeCalled(); + $entityManager->persist($virtualWallet)->shouldBeCalled(); + + $eventArgs = new PostUpdateEventArgs( + $vendor->getWrappedObject(), + $entityManager->getWrappedObject(), + ); + + $unitOfWork = Mockery::mock(UnitOfWork::class); + $unitOfWork->shouldReceive('getEntityChangeSet')->withArgs([$vendor->getWrappedObject()])->andReturn([ + 'settlementFrequency' => ['bar', VendorSettlementFrequency::VIRTUAL_WALLET], + ]); + $entityManager->getUnitOfWork()->willReturn($unitOfWork); + + $virtualWalletCreator->createForVendorAndChannel($vendor, $channel)->shouldNotBeCalled(); + $virtualWallet->withdraw($settlement)->shouldNotBeCalled(); + $entityManager->persist($virtualWallet)->shouldNotBeCalled(); + + $this->withdraw($settlement, $eventArgs); + } + + public function it_withdraws_for_virtual_wallet_previous_frequency( + SettlementInterface $settlement, + VendorInterface $vendor, + ChannelInterface $channel, + VirtualWalletInterface $virtualWallet, + VirtualWalletCreatorInterface $virtualWalletCreator, + EntityManagerInterface $entityManager, + ): void { + $settlement->getVendor()->willReturn($vendor); + $settlement->getChannel()->willReturn($channel); + + $vendor->getSettlementFrequency()->willReturn(VendorSettlementFrequency::WEEKLY); + $virtualWalletCreator->createForVendorAndChannel($vendor, $channel)->willReturn($virtualWallet); + $virtualWallet->withdraw($settlement)->shouldBeCalled(); + $entityManager->persist($virtualWallet)->shouldBeCalled(); + + $eventArgs = new PostUpdateEventArgs( + $vendor->getWrappedObject(), + $entityManager->getWrappedObject(), + ); + + $unitOfWork = Mockery::mock(UnitOfWork::class); + $unitOfWork->shouldReceive('getEntityChangeSet')->withArgs([$vendor->getWrappedObject()])->andReturn([ + 'settlementFrequency' => [VendorSettlementFrequency::VIRTUAL_WALLET, 'baz'], + ]); + $entityManager->getUnitOfWork()->willReturn($unitOfWork); + + $virtualWalletCreator->createForVendorAndChannel($vendor, $channel)->willReturn($virtualWallet); + $virtualWallet->withdraw($settlement)->shouldBeCalled(); + $entityManager->persist($virtualWallet)->shouldBeCalled(); + + $this->withdraw($settlement, $eventArgs); + } +} diff --git a/OpenMarketplace/spec/Component/Settlement/PeriodStrategy/MonthlySettlementPeriodResolverSpec.php b/OpenMarketplace/spec/Component/Settlement/PeriodStrategy/MonthlySettlementPeriodResolverSpec.php new file mode 100644 index 0000000..7f3a2f3 --- /dev/null +++ b/OpenMarketplace/spec/Component/Settlement/PeriodStrategy/MonthlySettlementPeriodResolverSpec.php @@ -0,0 +1,56 @@ +shouldHaveType(MonthlySettlementPeriodResolver::class); + } + + public function it_supports_vendor_when_settlement_frequency_is_monthly( + VendorInterface $vendor, + ): void { + $vendor->getSettlementFrequency()->willReturn('monthly'); + + $this->supports($vendor)->shouldBe(true); + } + + public function it_does_not_supports_vendor_when_settlement_frequency_is_not_monthly( + VendorInterface $vendor, + ): void { + $vendor->getSettlementFrequency()->willReturn('weekly'); + + $this->supports($vendor)->shouldBe(false); + } + + public function it_does_not_supports_vendor_when_settlement_frequency_is_not_cyclical( + VendorInterface $vendor, + ): void { + $vendor->getSettlementFrequency()->willReturn('monthly'); + + $this->supports($vendor, false)->shouldBe(false); + } + + public function it_returns_valid_next_settlement_start_and_end_date_time( + ): void { + $this->resolve()->shouldBeLike([ + new \DateTime('first day of last month 00:00:00'), + new \DateTime('last day of last month 23:59:59'), + ]); + } +} diff --git a/OpenMarketplace/spec/Component/Settlement/PeriodStrategy/QuarterlySettlementPeriodResolverSpec.php b/OpenMarketplace/spec/Component/Settlement/PeriodStrategy/QuarterlySettlementPeriodResolverSpec.php new file mode 100644 index 0000000..324b527 --- /dev/null +++ b/OpenMarketplace/spec/Component/Settlement/PeriodStrategy/QuarterlySettlementPeriodResolverSpec.php @@ -0,0 +1,56 @@ +shouldHaveType(QuarterlySettlementPeriodResolver::class); + } + + public function it_supports_vendor_when_settlement_frequency_is_quarterly( + VendorInterface $vendor, + ): void { + $vendor->getSettlementFrequency()->willReturn('quarterly'); + + $this->supports($vendor)->shouldBe(true); + } + + public function it_does_not_supports_vendor_when_settlement_frequency_is_not_quarterly( + VendorInterface $vendor, + ): void { + $vendor->getSettlementFrequency()->willReturn('weekly'); + + $this->supports($vendor)->shouldBe(false); + } + + public function it_does_not_supports_vendor_when_settlement_frequency_is_not_cyclical( + VendorInterface $vendor, + ): void { + $vendor->getSettlementFrequency()->willReturn('weekly'); + + $this->supports($vendor, false)->shouldBe(false); + } + + public function it_returns_valid_next_settlement_start_and_end_date_time( + ): void { + $this->resolve()->shouldBeLike([ + (new \DateTime())->setTimestamp(QuarterlySettlementPeriodResolver::getLastQuarterStartDate()), + (new \DateTime())->setTimestamp(QuarterlySettlementPeriodResolver::getLastQuarterEndDate()), + ]); + } +} diff --git a/OpenMarketplace/spec/Component/Settlement/PeriodStrategy/SettlementPeriodResolverSpec.php b/OpenMarketplace/spec/Component/Settlement/PeriodStrategy/SettlementPeriodResolverSpec.php new file mode 100644 index 0000000..48c29c7 --- /dev/null +++ b/OpenMarketplace/spec/Component/Settlement/PeriodStrategy/SettlementPeriodResolverSpec.php @@ -0,0 +1,144 @@ +beConstructedWith([ + $resolverA, + $resolverB, + ]); + } + + public function it_is_initializable() + { + $this->shouldHaveType(SettlementPeriodResolver::class); + } + + public function it_should_throw_exception_when_no_resolver_supports_vendor( + VendorInterface $vendor, + AbstractSettlementPeriodResolverStrategy $resolverA, + AbstractSettlementPeriodResolverStrategy $resolverB, + ): void { + $cyclical = true; + $vendorCreatedAt = new \DateTime('-2 month'); + + $vendor->getSettlementFrequency()->willReturn(VendorSettlementFrequency::MONTHLY); + $vendor->getCreatedAt()->willReturn($vendorCreatedAt); + + $resolverA->supports($vendor, $cyclical)->willReturn(false); + $resolverA->resolve($vendorCreatedAt)->shouldNotBeCalled(); + + $resolverB->supports($vendor, $cyclical)->willReturn(false); + $resolverB->resolve($vendorCreatedAt)->shouldNotBeCalled(); + + $this->shouldThrow(\InvalidArgumentException::class) + ->during('getSettlementDateRangeForVendor', [$vendor->getWrappedObject(), $cyclical, null]); + } + + public function it_should_call_only_one_resolver( + VendorInterface $vendor, + AbstractSettlementPeriodResolverStrategy $resolverA, + AbstractSettlementPeriodResolverStrategy $resolverB, + ): void { + $cyclical = true; + + $from = new \DateTime('-1 month'); + $to = new \DateTime(); + $vendorCreatedAt = new \DateTime('-2 month'); + + $vendor->getSettlementFrequency()->willReturn(VendorSettlementFrequency::MONTHLY); + $vendor->getCreatedAt()->willReturn($vendorCreatedAt); + + $resolverA->supports($vendor, $cyclical)->willReturn(true); + $resolverA->resolve($vendorCreatedAt)->willReturn([$from, $to]); + $resolverB->supports($vendor, $cyclical)->shouldNotBeCalled(); + $resolverB->resolve($vendorCreatedAt)->shouldNotBeCalled(); + + $this->getSettlementDateRangeForVendor($vendor, $cyclical)->shouldBeLike([$from, $to]); + } + + public function it_should_only_call_second_one_resolver( + VendorInterface $vendor, + AbstractSettlementPeriodResolverStrategy $resolverA, + AbstractSettlementPeriodResolverStrategy $resolverB, + ): void { + $cyclical = true; + + $from = new \DateTime('-1 month'); + $to = new \DateTime(); + $vendorCreatedAt = new \DateTime('-2 month'); + + $vendor->getSettlementFrequency()->willReturn(VendorSettlementFrequency::MONTHLY); + $vendor->getCreatedAt()->willReturn($vendorCreatedAt); + + $resolverB->supports($vendor, $cyclical)->willReturn(true); + $resolverB->resolve($vendorCreatedAt)->willReturn([$from, $to]); + $resolverA->supports($vendor, $cyclical)->willReturn(false); + + $resolverA->resolve($vendorCreatedAt)->shouldNotBeCalled(); + + $this->getSettlementDateRangeForVendor($vendor, $cyclical)->shouldBeLike([$from, $to]); + } + + public function it_should_provide_longer_period_if_from_smaller_than_last_settlement_ends_at( + VendorInterface $vendor, + AbstractSettlementPeriodResolverStrategy $resolverA, + AbstractSettlementPeriodResolverStrategy $resolverB, + ): void { + $cyclical = true; + + $vendorCreatedAt = new \DateTime('-2 months'); + $from = new \DateTime('-1 month'); + $lastSettlementsEndsAt = $from->modify('-1 week'); + $to = new \DateTime(); + + $vendor->getSettlementFrequency()->willReturn(VendorSettlementFrequency::MONTHLY); + $vendor->getCreatedAt()->willReturn($vendorCreatedAt); + + $resolverB->supports($vendor, $cyclical)->willReturn(true); + $resolverB->resolve($lastSettlementsEndsAt)->willReturn([$from, $to]); + $resolverA->supports($vendor, $cyclical)->willReturn(false); + $resolverA->resolve($lastSettlementsEndsAt)->shouldNotBeCalled(); + + $this->getSettlementDateRangeForVendor($vendor, $cyclical, $lastSettlementsEndsAt)->shouldBeLike([$lastSettlementsEndsAt->modify('+ 1 second'), $to]); + } + + public function it_should_use_not_created_at_from_vendor( + VendorInterface $vendor, + AbstractSettlementPeriodResolverStrategy $resolverA, + ): void { + $cyclical = true; + + $vendorCreatedAt = new \DateTime('-2 weeks'); + $from = new \DateTime('-1 month'); + $to = new \DateTime(); + + $vendor->getSettlementFrequency()->willReturn(VendorSettlementFrequency::MONTHLY); + $vendor->getCreatedAt()->willReturn($vendorCreatedAt); + + $resolverA->supports($vendor, $cyclical)->willReturn(true); + $resolverA->resolve($vendorCreatedAt)->willReturn([$from, $to]); + + $this->getSettlementDateRangeForVendor($vendor, $cyclical)->shouldBeLike([$from, $to]); + } +} diff --git a/OpenMarketplace/spec/Component/Settlement/PeriodStrategy/VirtualWalletSettlementPeriodResolverSpec.php b/OpenMarketplace/spec/Component/Settlement/PeriodStrategy/VirtualWalletSettlementPeriodResolverSpec.php new file mode 100644 index 0000000..22240ad --- /dev/null +++ b/OpenMarketplace/spec/Component/Settlement/PeriodStrategy/VirtualWalletSettlementPeriodResolverSpec.php @@ -0,0 +1,57 @@ +shouldHaveType(VirtualWalletSettlementPeriodResolver::class); + } + + public function it_supports_vendor_when_settlement_frequency_is_quarterly( + VendorInterface $vendor, + ): void { + $vendor->getSettlementFrequency()->willReturn(VendorSettlementFrequency::VIRTUAL_WALLET); + + $this->supports($vendor, false)->shouldBe(true); + } + + public function it_does_not_supports_vendor_when_settlement_frequency_is_not_quarterly( + VendorInterface $vendor, + ): void { + $vendor->getSettlementFrequency()->willReturn(VendorSettlementFrequency::MONTHLY); + + $this->supports($vendor, false)->shouldBe(false); + } + + public function it_does_not_supports_vendor_when_settlement_frequency_is_cyclical( + VendorInterface $vendor, + ): void { + $vendor->getSettlementFrequency()->willReturn(VendorSettlementFrequency::VIRTUAL_WALLET); + + $this->supports($vendor, true)->shouldBe(false); + } + + public function it_returns_valid_next_settlement_start_and_end_date_time( + ): void { + $lastSettlementEndsAt = new \DateTime('2021-01-01 00:00:00'); + [$start, $end] = $this->resolve($lastSettlementEndsAt); + $start->shouldBeLike($lastSettlementEndsAt->modify('+1 second')); + $end->format('Y-m-d H:i')->shouldBe((new \DateTime())->format('Y-m-d H:i')); + } +} diff --git a/OpenMarketplace/spec/Component/Settlement/PeriodStrategy/WeeklySettlementPeriodResolverSpec.php b/OpenMarketplace/spec/Component/Settlement/PeriodStrategy/WeeklySettlementPeriodResolverSpec.php new file mode 100644 index 0000000..d9c43a7 --- /dev/null +++ b/OpenMarketplace/spec/Component/Settlement/PeriodStrategy/WeeklySettlementPeriodResolverSpec.php @@ -0,0 +1,56 @@ +shouldHaveType(WeeklySettlementPeriodResolver::class); + } + + public function it_supports_vendor_when_settlement_frequency_is_weekly( + VendorInterface $vendor, + ): void { + $vendor->getSettlementFrequency()->willReturn('weekly'); + + $this->supports($vendor)->shouldBe(true); + } + + public function it_does_not_supports_vendor_when_settlement_frequency_is_not_weekly( + VendorInterface $vendor, + ): void { + $vendor->getSettlementFrequency()->willReturn('monthly'); + + $this->supports($vendor)->shouldBe(false); + } + + public function it_does_not_supports_vendor_when_settlement_frequency_is_not_cyclical( + VendorInterface $vendor, + ): void { + $vendor->getSettlementFrequency()->willReturn('weekly'); + + $this->supports($vendor, false)->shouldBe(false); + } + + public function it_returns_valid_next_settlement_start_and_end_date_time( + ): void { + $this->resolve()->shouldBeLike([ + new \DateTime('last week monday 00:00:00'), + new \DateTime('last week sunday 23:59:59'), + ]); + } +} diff --git a/OpenMarketplace/spec/Component/Settlement/Sender/SettlementsCreatedEmailSenderSpec.php b/OpenMarketplace/spec/Component/Settlement/Sender/SettlementsCreatedEmailSenderSpec.php new file mode 100644 index 0000000..0b32c64 --- /dev/null +++ b/OpenMarketplace/spec/Component/Settlement/Sender/SettlementsCreatedEmailSenderSpec.php @@ -0,0 +1,58 @@ +beConstructedWith( + $sender, + $logger, + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(SettlementsCreatedEmailSender::class); + } + + public function it_sends_email( + VendorInterface $vendor, + SettlementInterface $settlement, + ShopUserInterface $shopUser, + ChannelInterface $channel, + ): void { + $settlements = [$settlement->getWrappedObject()]; + $vendor->getShopUser()->willReturn($shopUser); + $shopUser->getEmail()->willReturn('email@domain.com'); + $settlement->getStartDate()->willReturn(new \DateTime('-1 month')); + $settlement->getEndDate()->willReturn(new \DateTime()); + $settlement->getTotalCommissionAmount()->willReturn(1000); + $settlement->getChannel()->willReturn($channel); + + $channel->getName()->willReturn('Open Marketplace'); + + $this->send($vendor, $settlements); + } +} diff --git a/OpenMarketplace/spec/Component/Vendor/Entity/LogoImageSpec.php b/OpenMarketplace/spec/Component/Vendor/Entity/LogoImageSpec.php new file mode 100644 index 0000000..0533dae --- /dev/null +++ b/OpenMarketplace/spec/Component/Vendor/Entity/LogoImageSpec.php @@ -0,0 +1,44 @@ +shouldHaveType(LogoImage::class); + } + + public function it_should_implement_interface(): void + { + $this->shouldImplement(LogoImageInterface::class); + } + + public function it_gets_path(): void + { + $this->setPath('test'); + + $this->getPath()->shouldReturn('test'); + } + + public function it_gets_vendor(VendorInterface $vendor): void + { + $this->setOwner($vendor); + + $this->getOwner()->shouldReturn($vendor); + } +} diff --git a/OpenMarketplace/spec/Component/Vendor/Entity/ShopUserSpec.php b/OpenMarketplace/spec/Component/Vendor/Entity/ShopUserSpec.php new file mode 100644 index 0000000..901f0b9 --- /dev/null +++ b/OpenMarketplace/spec/Component/Vendor/Entity/ShopUserSpec.php @@ -0,0 +1,73 @@ +shouldHaveType(ShopUser::class); + $this->shouldHaveType(BasicShopUser::class); + $this->shouldHaveType(ShopUserInterface::class); + } + + public function it_get_roles_for_user_without_vendor(): void + { + $this->addRole(self::ROLE_USER); + + $this->getRoles()->shouldReturn([self::ROLE_USER]); + } + + public function it_get_roles_for_user_with_not_verified_vendor( + VendorInterface $vendor, + ): void { + $vendor->isVerified()->willReturn(false); + + $this->addRole(self::ROLE_USER); + $this->setVendor($vendor); + + $this->getRoles()->shouldReturn([self::ROLE_USER]); + } + + public function it_get_roles_for_user_with_not_enabled_vendor( + VendorInterface $vendor, + ): void { + $vendor->isVerified()->willReturn(true); + $vendor->isEnabled()->willReturn(false); + + $this->addRole(self::ROLE_USER); + $this->setVendor($vendor); + + $this->getRoles()->shouldReturn([self::ROLE_USER]); + } + + public function it_get_roles_for_user_with_vendor( + VendorInterface $vendor, + ): void { + $vendor->isVerified()->willReturn(true); + $vendor->isEnabled()->willReturn(true); + + $this->addRole(self::ROLE_USER); + $this->setVendor($vendor); + + $this->getRoles()->shouldReturn([self::ROLE_USER, self::ROLE_VENDOR]); + } +} diff --git a/OpenMarketplace/spec/Component/Vendor/Entity/VendorSpec.php b/OpenMarketplace/spec/Component/Vendor/Entity/VendorSpec.php new file mode 100644 index 0000000..798f5cd --- /dev/null +++ b/OpenMarketplace/spec/Component/Vendor/Entity/VendorSpec.php @@ -0,0 +1,57 @@ +shouldHaveType(Vendor::class); + } + + public function it_should_implement_interface(): void + { + $this->shouldImplement(VendorInterface::class); + } + + public function it_has_shipping_method(VendorShippingMethodInterface $shippingMethod): void + { + $this->addShippingMethod($shippingMethod); + + $this->hasShippingMethod($shippingMethod)->shouldReturn(true); + } + + public function it_doesnt_have_shipping_method(VendorShippingMethodInterface $shippingMethod): void + { + $this->hasShippingMethod($shippingMethod)->shouldReturn(false); + } + + public function it_adds_shipping_method(VendorShippingMethodInterface $shippingMethod): void + { + $this->addShippingMethod($shippingMethod); + + $this->getShippingMethods()->contains($shippingMethod)->shouldBe(true); + } + + public function it_removes_shipping_method(VendorShippingMethodInterface $shippingMethod): void + { + $this->addShippingMethod($shippingMethod); + $this->removeShippingMethod($shippingMethod); + + $this->getShippingMethods()->contains($shippingMethod)->shouldBe(false); + } +} diff --git a/OpenMarketplace/spec/Component/Vendor/Generator/SlugGeneratorSpec.php b/OpenMarketplace/spec/Component/Vendor/Generator/SlugGeneratorSpec.php new file mode 100644 index 0000000..91552b1 --- /dev/null +++ b/OpenMarketplace/spec/Component/Vendor/Generator/SlugGeneratorSpec.php @@ -0,0 +1,50 @@ +beConstructedWith( + $vendorRepository + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(SlugGenerator::class); + } + + public function it_should_implement_interface(): void + { + $this->shouldImplement(SlugGeneratorInterface::class); + } + + public function it_generates_slug( + VendorRepositoryInterface $vendorRepository + ): void { + $vendorRepository->findOneBy(['slug' => 'test-company']) + ->willReturn(null); + + $this->generateSlug('test company') + ->shouldReturn('test-company'); + + $this->generateSlug('test company'); + } +} diff --git a/OpenMarketplace/spec/Component/Vendor/Profile/BackgroundImageOperatorSpec.php b/OpenMarketplace/spec/Component/Vendor/Profile/BackgroundImageOperatorSpec.php new file mode 100644 index 0000000..ad7d8c4 --- /dev/null +++ b/OpenMarketplace/spec/Component/Vendor/Profile/BackgroundImageOperatorSpec.php @@ -0,0 +1,72 @@ +beConstructedWith( + $entityManager, + $vendorBackgroundImageFactory + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(BackgroundImageOperator::class); + } + + public function it_replaces_background_image( + EntityManager $entityManager, + ProfileUpdateInterface $vendorData, + VendorInterface $vendor, + BackgroundImageInterface $updateImage, + BackgroundImageInterface $oldImage, + BackgroundImageInterface $newImage + ): void { + $vendorData->getBackgroundImage()->willReturn($updateImage); + $vendor->getBackgroundImage()->willReturn($oldImage); + $updateImage->getPath()->willReturn('path/to/file'); + + $this->replaceVendorImage($vendorData, $vendor); + + $oldImage->setPath('path/to/file')->shouldHaveBeenCalledOnce(); + $oldImage->setOwner($vendor)->shouldHaveBeenCalledOnce(); + $vendor->setBackgroundImage($oldImage)->shouldHaveBeenCalledOnce(); + + $updateImage->setPath(null)->shouldHaveBeenCalledOnce(); + $entityManager->persist($updateImage)->shouldHaveBeenCalledOnce(); + } + + public function it_does_nothing_when_no_update( + EntityManager $entityManager, + ProfileUpdateInterface $vendorData, + VendorInterface $vendor, + BackgroundImageInterface $updateImage, + ): void { + $vendorData->getBackgroundImage()->willReturn(null); + + $this->replaceVendorImage($vendorData, $vendor); + $entityManager->persist($updateImage)->shouldNotBeCalled(); + } +} diff --git a/OpenMarketplace/spec/Component/Vendor/Profile/Factory/AddressFactorySpec.php b/OpenMarketplace/spec/Component/Vendor/Profile/Factory/AddressFactorySpec.php new file mode 100644 index 0000000..1d4254b --- /dev/null +++ b/OpenMarketplace/spec/Component/Vendor/Profile/Factory/AddressFactorySpec.php @@ -0,0 +1,35 @@ +shouldHaveType(AddressFactory::class); + } + + public function it_returns_valid_address(Country $country): void + { + $address = $this->createAddress('some street', 'City', '22-111', $country); + $address->getCountry()->shouldBeEqualTo($country); + $address->shouldHaveType(AddressInterface::class); + $address->getStreet()->shouldBeEqualTo('some street'); + $address->getCity()->shouldBeEqualTo('City'); + $address->getPostalCode()->shouldBeEqualTo('22-111'); + } +} diff --git a/OpenMarketplace/spec/Component/Vendor/Profile/Factory/BackgroundImageFactorySpec.php b/OpenMarketplace/spec/Component/Vendor/Profile/Factory/BackgroundImageFactorySpec.php new file mode 100644 index 0000000..6baee00 --- /dev/null +++ b/OpenMarketplace/spec/Component/Vendor/Profile/Factory/BackgroundImageFactorySpec.php @@ -0,0 +1,49 @@ +shouldHaveType(BackgroundImageFactory::class); + } + + public function it_should_implement_interface(): void + { + $this->shouldImplement(BackgroundImageFactoryInterface::class); + } + + public function it_should_create_empty_vendor_image(): void + { + $vendorImage = new BackgroundImage(); + + $this->createNew()->shouldBeLike($vendorImage); + } + + public function it_should_create_vendor_image_with_data(): void + { + $vendor = new Vendor(); + $vendorImage = new BackgroundImage(); + + $vendorImage->setPath('test'); + $vendorImage->setOwner($vendor); + + $this->create('test', $vendor)->shouldBeLike($vendorImage); + } +} diff --git a/OpenMarketplace/spec/Component/Vendor/Profile/Factory/LogoImageFactorySpec.php b/OpenMarketplace/spec/Component/Vendor/Profile/Factory/LogoImageFactorySpec.php new file mode 100644 index 0000000..b40ff4f --- /dev/null +++ b/OpenMarketplace/spec/Component/Vendor/Profile/Factory/LogoImageFactorySpec.php @@ -0,0 +1,49 @@ +shouldHaveType(LogoImageFactory::class); + } + + public function it_should_implement_interface(): void + { + $this->shouldImplement(LogoImageFactoryInterface::class); + } + + public function it_should_create_empty_vendor_image(): void + { + $vendorImage = new LogoImage(); + + $this->createNew()->shouldBeLike($vendorImage); + } + + public function it_should_create_vendor_image_with_data(): void + { + $vendor = new Vendor(); + $vendorImage = new LogoImage(); + + $vendorImage->setPath('test'); + $vendorImage->setOwner($vendor); + + $this->create('test', $vendor)->shouldBeLike($vendorImage); + } +} diff --git a/OpenMarketplace/spec/Component/Vendor/Profile/Factory/ProfileFactorySpec.php b/OpenMarketplace/spec/Component/Vendor/Profile/Factory/ProfileFactorySpec.php new file mode 100644 index 0000000..7e3ae42 --- /dev/null +++ b/OpenMarketplace/spec/Component/Vendor/Profile/Factory/ProfileFactorySpec.php @@ -0,0 +1,49 @@ +beConstructedWith( + $vendorFactory + ); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(ProfileFactory::class); + } + + public function it_returns_vendor(FactoryInterface $vendorFactory): void + { + $vendorFactory->createNew()->willReturn(new Vendor()); + $this->createNew()->shouldHaveType(ProfileInterface::class); + } + + public function it_returns_valid_address(AddressInterface $vendorAddress, FactoryInterface $vendorFactory): void + { + $vendorFactory->createNew()->willReturn(new Vendor()); + $vendor = $this->createVendor('some street', 'City', 'iban', '22-111', 'description', $vendorAddress); + $vendor->shouldHaveType(ProfileInterface::class); + $vendor->getVendorAddress()->shouldBeEqualTo($vendorAddress); + } +} diff --git a/OpenMarketplace/spec/Component/Vendor/Profile/Factory/ProfileUpdateFactorySpec.php b/OpenMarketplace/spec/Component/Vendor/Profile/Factory/ProfileUpdateFactorySpec.php new file mode 100644 index 0000000..8789e9c --- /dev/null +++ b/OpenMarketplace/spec/Component/Vendor/Profile/Factory/ProfileUpdateFactorySpec.php @@ -0,0 +1,47 @@ +beConstructedWith($tokenGenerator); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(ProfileUpdateFactory::class); + } + + public function it_creates_vendor_profile_update( + TokenGeneratorInterface $tokenGenerator, + VendorInterface $vendor + ): void { + $tokenGenerator->generate()->willReturn('test_token'); + $this->createWithGeneratedTokenAndVendor($vendor)->shouldHaveType(ProfileUpdateInterface::class); + } + + public function it_creates_vendor_profile_update_with_valid_token( + TokenGeneratorInterface $tokenGenerator, + VendorInterface $vendor + ): void { + $tokenGenerator->generate()->willReturn('test_token'); + $this->createWithGeneratedTokenAndVendor($vendor)->getToken()->shouldBeEqualTo('test_token'); + } +} diff --git a/OpenMarketplace/spec/Component/Vendor/Profile/Factory/ProfileUpdateLogoImageFactorySpec.php b/OpenMarketplace/spec/Component/Vendor/Profile/Factory/ProfileUpdateLogoImageFactorySpec.php new file mode 100644 index 0000000..b4d653a --- /dev/null +++ b/OpenMarketplace/spec/Component/Vendor/Profile/Factory/ProfileUpdateLogoImageFactorySpec.php @@ -0,0 +1,42 @@ +shouldHaveType(ProfileUpdateLogoImageFactory::class); + } + + public function it_creates_new_vendor_image(): void + { + $this->createNew()->shouldBeAnInstanceOf(LogoImage::class); + } + + public function it_creates_initialized_image( + LogoImageInterface $uploadedImage, + ProfileInterface $vendorProfile + ): void { + $imageEntity = $this->createWithFileAndOwner($uploadedImage, $vendorProfile); + + $imageEntity->shouldBeAnInstanceOf(LogoImage::class); + $imageEntity->shouldImplement(LogoImageInterface::class); + $imageEntity->getOwner()->shouldBe($vendorProfile); + } +} diff --git a/OpenMarketplace/spec/Component/Vendor/Profile/LogoImageOperatorSpec.php b/OpenMarketplace/spec/Component/Vendor/Profile/LogoImageOperatorSpec.php new file mode 100644 index 0000000..e30c852 --- /dev/null +++ b/OpenMarketplace/spec/Component/Vendor/Profile/LogoImageOperatorSpec.php @@ -0,0 +1,105 @@ +beConstructedWith( + $entityManager, + $vendorImageFactory + ); + } + + public function it_is_initializable() + { + $this->shouldHaveType(LogoImageOperator::class); + } + + public function it_replaces_logo( + EntityManager $entityManager, + ProfileUpdateInterface $vendorData, + VendorInterface $vendor, + LogoImageInterface $updateImage, + LogoImageInterface $oldImage, + LogoImageInterface $newImage + ): void { + $vendorData->getImage()->willReturn($updateImage); + $vendor->getImage()->willReturn($oldImage); + $updateImage->getPath()->willReturn('path/to/file'); + + $this->replaceVendorImage($vendorData, $vendor); + + $oldImage->setPath('path/to/file')->shouldHaveBeenCalledOnce(); + $oldImage->setOwner($vendor)->shouldHaveBeenCalledOnce(); + $vendor->setImage($oldImage)->shouldHaveBeenCalledOnce(); + + $updateImage->setPath(null)->shouldHaveBeenCalledOnce(); + } + + public function it_creates_new_logo_entity( + EntityManager $entityManager, + ProfileUpdateInterface $vendorData, + VendorInterface $vendor, + LogoImageInterface $updateImage, + LogoImageInterface $oldImage, + LogoImageFactoryInterface $vendorImageFactory, + LogoImageInterface $newImage + ): void { + $vendorData->getImage()->willReturn($updateImage); + $vendor->getImage()->willReturn(null); + $updateImage->getPath()->willReturn('path/to/file'); + $vendorImageFactory->createNew()->willReturn($newImage); + + $this->replaceVendorImage($vendorData, $vendor); + + $newImage->setPath('path/to/file')->shouldHaveBeenCalledOnce(); + $newImage->setOwner($vendor)->shouldHaveBeenCalledOnce(); + $vendor->setImage($newImage)->shouldHaveBeenCalledOnce(); + + $updateImage->setPath(null)->shouldHaveBeenCalledOnce(); + } + + public function it_does_nothing_when_for_empty_image( + EntityManager $entityManager, + ProfileUpdateInterface $vendorData, + VendorInterface $vendor, + LogoImageInterface $updateImage, + LogoImageInterface $oldImage, + LogoImageFactoryInterface $vendorImageFactory, + LogoImageInterface $newImage + ): void { + $vendorData->getImage()->willReturn(null); + $vendor->getImage()->willReturn(null); + $updateImage->getPath()->willReturn('path/to/file'); + $vendorImageFactory->createNew()->willReturn($newImage); + + $this->replaceVendorImage($vendorData, $vendor); + + $newImage->setPath('path/to/file')->shouldNotHaveBeenCalled(); + $newImage->setOwner($vendor)->shouldNotHaveBeenCalled(); + $vendor->setImage($newImage)->shouldNotHaveBeenCalled(); + + $updateImage->setPath(null)->shouldNotHaveBeenCalled(); + } +} diff --git a/OpenMarketplace/spec/Component/Vendor/Profile/ProfileUpdateRemoverSpec.php b/OpenMarketplace/spec/Component/Vendor/Profile/ProfileUpdateRemoverSpec.php new file mode 100644 index 0000000..00f3b21 --- /dev/null +++ b/OpenMarketplace/spec/Component/Vendor/Profile/ProfileUpdateRemoverSpec.php @@ -0,0 +1,70 @@ +beConstructedWith($entityManager); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(ProfileUpdateRemover::class); + $this->shouldImplement(ProfileUpdateRemoverInterface::class); + } + + public function it_removes_profile_update( + EntityManagerInterface $entityManager, + ProfileUpdateInterface $vendorProfileUpdate + ): void { + $vendorProfileUpdate->getVendorAddress() + ->willReturn(null); + + $entityManager->remove($vendorProfileUpdate) + ->shouldBeCalledOnce(); + + $entityManager->flush() + ->shouldBeCalledOnce(); + + $this->removePendingUpdate($vendorProfileUpdate); + } + + public function it_removes_profile_update_and_address_update( + EntityManagerInterface $entityManager, + ProfileUpdateInterface $vendorProfileUpdate, + AddressInterface $vendorProfileAddressUpdate + ): void { + $vendorProfileUpdate->getVendorAddress() + ->willReturn($vendorProfileAddressUpdate); + + $entityManager->remove($vendorProfileAddressUpdate) + ->shouldBeCalledOnce(); + + $entityManager->remove($vendorProfileUpdate) + ->shouldBeCalledOnce(); + + $entityManager->flush() + ->shouldBeCalledOnce(); + + $this->removePendingUpdate($vendorProfileUpdate); + } +} diff --git a/OpenMarketplace/spec/Component/Vendor/Profile/TokenGeneratorSpec.php b/OpenMarketplace/spec/Component/Vendor/Profile/TokenGeneratorSpec.php new file mode 100644 index 0000000..926f8f6 --- /dev/null +++ b/OpenMarketplace/spec/Component/Vendor/Profile/TokenGeneratorSpec.php @@ -0,0 +1,32 @@ +shouldHaveType(TokenGenerator::class); + } + + public function it_generates_random_tokens(): void + { + $token1 = $this->generate(); + $token2 = $this->generate(); + $token1->shouldBeString(); + $token2->shouldBeString(); + $token1->shouldNotBeEqualTo($token2); + } +} diff --git a/OpenMarketplace/spec/Component/Vendor/ProfileUpdaterSpec.php b/OpenMarketplace/spec/Component/Vendor/ProfileUpdaterSpec.php new file mode 100644 index 0000000..79f5e36 --- /dev/null +++ b/OpenMarketplace/spec/Component/Vendor/ProfileUpdaterSpec.php @@ -0,0 +1,178 @@ +beConstructedWith( + $entityManager, + $sender, + $remover, + $vendorProfileFactory, + $imageFactory, + $backgroundImageFactory, + $imageUploader, + $vendorLogoOperator, + $VendorBackgroundImageOperator + ); + } + + public function it_is_initializable() + { + $this->shouldHaveType(ProfileUpdaterInterface::class); + } + + public function it_calls_entity_manager( + EntityManagerInterface $entityManager, + VendorInterface $vendor, + ProfileInterface $vendorData, + AddressInterface $vendorAddress + ): void { + $vendorData->getCompanyName()->willReturn('CompanyName'); + $vendorData->getTaxIdentifier()->willReturn('TaxIdentifier'); + $vendorData->getBankAccountNumber()->willReturn('iban'); + $vendorData->getPhoneNumber()->willReturn('11339321'); + $vendorData->getDescription()->willReturn('description'); + $vendorData->getVendorAddress()->willReturn($vendorAddress); + + $this->setVendorFromData($vendor, $vendorData); + + $entityManager->flush()->shouldHaveBeenCalled(1); + $entityManager->persist($vendor)->shouldHaveBeenCalledTimes(1); + } + + public function it_sends_email_after_creating_pending_data( + SenderInterface $sender, + ProfileUpdateFactoryInterface $vendorProfileFactory, + VendorInterface $vendor, + ProfileInterface $vendorData, + ProfileUpdateInterface $newPendingUpdate, + ShopUserInterface $user, + AddressInterface $vendorAddressUpdate, + LogoImageInterface $imageFromForm, + BackgroundImageInterface $backgroundImageFromForm + ): void { + $vendorProfileFactory->createWithGeneratedTokenAndVendor($vendor)->willReturn($newPendingUpdate); + $newPendingUpdate->getToken()->willReturn('testing-token'); + $vendorData->getCompanyName()->willReturn('testcompany'); + $vendorData->getTaxIdentifier()->willReturn('testTaxID'); + $vendorData->getBankAccountNumber()->willReturn('testIban'); + $vendorData->getPhoneNumber()->willReturn('testNumber'); + $vendorData->getDescription()->willReturn('description'); + $vendorData->getVendorAddress()->willReturn($vendorAddressUpdate); + $imageFromForm->getFile()->willReturn(null); + $imageFromForm->getPath()->willReturn('path/to/file'); + $backgroundImageFromForm->getFile()->willReturn(null); + $backgroundImageFromForm->getPath()->willReturn('path/to/file'); + $newPendingUpdate->getVendorAddress()->shouldBeCalled(); + + $newPendingUpdate->setCompanyName('testcompany')->shouldBeCalled(); + $newPendingUpdate->setTaxIdentifier('testTaxID')->shouldBeCalled(); + $newPendingUpdate->setBankAccountNumber('testIban')->shouldBeCalled(); + $newPendingUpdate->setPhoneNumber('testNumber')->shouldBeCalled(); + $newPendingUpdate->setDescription('description')->shouldBeCalled(); + + $vendor->getShopUser()->willReturn($user); + + $user->getEmail()->willReturn('test@mail.at'); + + $this->createPendingVendorProfileUpdate($vendorData, $vendor, $imageFromForm, $backgroundImageFromForm); + + $sender->send('vendor_profile_update', ['test@mail.at'], ['token' => 'testing-token']) + ->shouldHaveBeenCalledTimes(1); + } + + public function it_creates_new_image_object_for_new_image_upload( + SenderInterface $sender, + ProfileUpdateFactoryInterface $vendorProfileFactory, + VendorInterface $vendor, + ProfileInterface $vendorData, + ProfileUpdateInterface $newPendingUpdate, + ShopUserInterface $user, + AddressInterface $vendorAddressUpdate, + LogoImageInterface $imageFromForm, + ProfileUpdateLogoImageFactoryInterface $imageFactory, + LogoImageInterface $newImage, + BackgroundImageInterface $backgroundImageFromForm, + ProfileUpdateBackgroundImageFactoryInterface $backgroundImageFactory, + BackgroundImageInterface $newBackgroundImage, + ImageUploader $imageUploader, + SplFileInfo $fileInfo + ): void { + $vendorProfileFactory->createWithGeneratedTokenAndVendor($vendor)->willReturn($newPendingUpdate); + $newPendingUpdate->getToken()->willReturn('testing-token'); + $vendorData->getCompanyName()->willReturn('testcompany'); + $vendorData->getTaxIdentifier()->willReturn('testTaxID'); + $vendorData->getBankAccountNumber()->willReturn('testIban'); + $vendorData->getPhoneNumber()->willReturn('testNumber'); + $vendorData->getDescription()->willReturn('description'); + $vendorData->getVendorAddress()->willReturn($vendorAddressUpdate); + + $imageFromForm->getFile()->willReturn($fileInfo); + $imageFactory->createWithFileAndOwner($imageFromForm, $newPendingUpdate)->willReturn($newImage); + $imageUploader->upload($newImage); + $newPendingUpdate->setImage($newImage)->shouldBeCalledOnce(); + + $backgroundImageFromForm->getFile()->willReturn($fileInfo); + $backgroundImageFactory->createWithFileAndOwner($backgroundImageFromForm, $newPendingUpdate)->willReturn($newBackgroundImage); + $imageUploader->upload($newBackgroundImage); + $newPendingUpdate->setBackgroundImage($newBackgroundImage)->shouldBeCalledOnce(); + + $newPendingUpdate->getVendorAddress()->shouldBeCalled(); + + $newPendingUpdate->setCompanyName('testcompany')->shouldBeCalled(); + $newPendingUpdate->setTaxIdentifier('testTaxID')->shouldBeCalled(); + $newPendingUpdate->setBankAccountNumber('testIban')->shouldBeCalled(); + $newPendingUpdate->setPhoneNumber('testNumber')->shouldBeCalled(); + $newPendingUpdate->setDescription('description')->shouldBeCalled(); + $imageFromForm->getPath()->willReturn('path/to/file'); + $backgroundImageFromForm->getPath()->willReturn('path/to/file'); + $vendor->getShopUser()->willReturn($user); + $user->getEmail()->willReturn('test@mail.at'); + + $this->createPendingVendorProfileUpdate($vendorData, $vendor, $imageFromForm, $backgroundImageFromForm); + + $sender->send('vendor_profile_update', ['test@mail.at'], ['token' => 'testing-token']) + ->shouldHaveBeenCalledTimes(1); + } +} diff --git a/OpenMarketplace/spec/Component/Vendor/VendorContextSpec.php b/OpenMarketplace/spec/Component/Vendor/VendorContextSpec.php new file mode 100644 index 0000000..7c951b6 --- /dev/null +++ b/OpenMarketplace/spec/Component/Vendor/VendorContextSpec.php @@ -0,0 +1,70 @@ +beConstructedWith($security); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(VendorContext::class); + $this->shouldImplement(VendorContextInterface::class); + } + + public function it_throws_exception_when_no_user_got_from_security( + Security $security + ): void { + $security->getUser()->willReturn(null); + + $this->shouldThrow(ShopUserNotFoundException::class) + ->during('getVendor', []); + } + + public function it_throws_exception_when_shop_user_has_no_vendor_context( + Security $security, + ShopUserInterface $shopUser + ): void { + $security->getUser()->willReturn($shopUser); + + $shopUser->getVendor()->willReturn(null); + + $this->shouldThrow(ShopUserHasNoVendorContextException::class) + ->during('getVendor', []); + } + + public function it_returns_vendor_from_shop_user_context( + Security $security, + ShopUserInterface $shopUser, + VendorInterface $vendor + ): void { + $security->getUser()->willReturn($shopUser); + + $shopUser->getVendor()->willReturn($vendor); + + $this->getVendor() + ->shouldReturn($vendor); + } +} diff --git a/OpenMarketplace/spec/testfiles/test.txt b/OpenMarketplace/spec/testfiles/test.txt new file mode 100644 index 0000000..d74007f --- /dev/null +++ b/OpenMarketplace/spec/testfiles/test.txt @@ -0,0 +1 @@ +testing file diff --git a/OpenMarketplace/src/Component/Channel/Repository/ChannelRepository.php b/OpenMarketplace/src/Component/Channel/Repository/ChannelRepository.php new file mode 100644 index 0000000..ca50de8 --- /dev/null +++ b/OpenMarketplace/src/Component/Channel/Repository/ChannelRepository.php @@ -0,0 +1,38 @@ +createQueryBuilder('o') + ->andWhere('o.enabled = true') + ->getQuery() + ->getResult() + ; + } + + public function findOneEnabledByCode(string $code): ?ChannelInterface + { + return $this->createQueryBuilder('o') + ->andWhere('o.code = :code') + ->andWhere('o.enabled = true') + ->setParameter('code', $code) + ->getQuery() + ->getOneOrNullResult() + ; + } +} diff --git a/OpenMarketplace/src/Component/Channel/Repository/ChannelRepositoryInterface.php b/OpenMarketplace/src/Component/Channel/Repository/ChannelRepositoryInterface.php new file mode 100644 index 0000000..a8c29bf --- /dev/null +++ b/OpenMarketplace/src/Component/Channel/Repository/ChannelRepositoryInterface.php @@ -0,0 +1,22 @@ +attributes->get('_sylius')['redirect']; + + $archiveRequestMessage = $this->messageFactory->createNewWithArchiveRequest(); + + $this->messagePersister + ->createWithConversation($id, $archiveRequestMessage, null, false); + + /** @var Session $session */ + $session = $this->requestStack->getSession(); + $session->getFlashBag()->add('success', 'open_marketplace.ui.archive_message_send'); + + return new RedirectResponse($this->urlGenerator->generate($redirect, [ + 'id' => $id, + ])); + } +} diff --git a/OpenMarketplace/src/Component/Core/Admin/Controller/ProductListing/AcceptAction.php b/OpenMarketplace/src/Component/Core/Admin/Controller/ProductListing/AcceptAction.php new file mode 100644 index 0000000..a3d3e19 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Controller/ProductListing/AcceptAction.php @@ -0,0 +1,46 @@ +productListingRepository->find($request->attributes->get('id')); + + /** @var DraftInterface $latestProductDraft */ + $latestProductDraft = $this->productDraftRepository->findLatestDraft($productListing); + + $this->productDraftStateMachineTransition->applyIfCan($latestProductDraft, DraftTransitions::TRANSITION_ACCEPT); + + return new RedirectResponse($this->router->generate('open_marketplace_admin_product_listing_index')); + } +} diff --git a/OpenMarketplace/src/Component/Core/Admin/Controller/ProductListing/RejectAction.php b/OpenMarketplace/src/Component/Core/Admin/Controller/ProductListing/RejectAction.php new file mode 100644 index 0000000..9e281d5 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Controller/ProductListing/RejectAction.php @@ -0,0 +1,46 @@ +productListingRepository->find($request->attributes->get('id')); + + /** @var DraftInterface $latestProductDraft */ + $latestProductDraft = $this->productDraftRepository->findLatestDraft($productListing); + + $this->productDraftStateMachineTransition->applyIfCan($latestProductDraft, DraftTransitions::TRANSITION_REJECT); + + return new RedirectResponse($this->router->generate('open_marketplace_admin_product_listing_index')); + } +} diff --git a/OpenMarketplace/src/Component/Core/Admin/Controller/ProductListing/RestoreAction.php b/OpenMarketplace/src/Component/Core/Admin/Controller/ProductListing/RestoreAction.php new file mode 100644 index 0000000..26c97c2 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Controller/ProductListing/RestoreAction.php @@ -0,0 +1,53 @@ +productListingRepository->find($request->attributes->get('id')); + + $productListing->restore(); + + $product = $productListing->getProduct(); + + if ($product) { + $product->setEnabled(true); + $this->entityManager->persist($product); + } + + $this->entityManager->persist($productListing); + $this->entityManager->flush(); + + $this->flashBag->set('success', 'open_marketplace.ui.restored'); + + return new RedirectResponse($this->router->generate('open_marketplace_admin_product_listing_index')); + } +} diff --git a/OpenMarketplace/src/Component/Core/Admin/Controller/ProductListing/ShowAction.php b/OpenMarketplace/src/Component/Core/Admin/Controller/ProductListing/ShowAction.php new file mode 100644 index 0000000..9fcdc76 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Controller/ProductListing/ShowAction.php @@ -0,0 +1,101 @@ +productListingRepository->find($request->attributes->get('id')); + + /** @var DraftInterface $latestProductDraft */ + $latestProductDraft = $this->productDraftRepository->findLatestDraft($productListing); + + $conversation = new Conversation(); + + $form = $this->formFactory->create(ConversationType::class, $conversation); + + $form->handleRequest($request); + $draftViewURL = $this->router->generate( + 'open_marketplace_vendor_product_listings_show', + ['id' => $latestProductDraft->getId()], + UrlGenerator::ABSOLUTE_URL + ); + + if ($form->isSubmitted() && $form->isValid()) { + /** @var ConversationInterface $conversation */ + $conversation = $form->getData(); + $conversation->setShopUser($productListing->getVendor()->getShopUser()); + $conversation->setRejectedListingURL($draftViewURL); + $this->conversationRepository->add($conversation); + + $this->addConversationWithMessages($conversation); + + return new RedirectResponse($this->router->generate( + 'open_marketplace_admin_product_listing_reject', + ['id' => $request->attributes->get('id')] + )); + } + + return new Response( + $this->twig->render('Context/Admin/ProductListing/show.html.twig', [ + 'productListing' => $productListing, + 'productDraft' => $latestProductDraft, + 'form' => $form->createView(), + ]) + ); + } + + private function addConversationWithMessages(ConversationInterface $conversation): void + { + if (null !== $conversation->getMessages()) { + /** @var MessageInterface $message */ + foreach ($conversation->getMessages()->toArray() as $message) { + $this->messagePersister->createWithConversation( + $conversation->getId(), + $message, + $message->getFile(), + ); + } + } + } +} diff --git a/OpenMarketplace/src/Component/Core/Admin/Form/Type/ProductListingStatusFilterType.php b/OpenMarketplace/src/Component/Core/Admin/Form/Type/ProductListingStatusFilterType.php new file mode 100644 index 0000000..e722534 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Form/Type/ProductListingStatusFilterType.php @@ -0,0 +1,43 @@ +add( + 'status', + ChoiceType::class, + [ + 'label' => false, + 'choices' => [ + self::STATUS_UNDER_VERIFICATION => DraftInterface::STATUS_UNDER_VERIFICATION, + self::STATUS_VERIFIED => DraftInterface::STATUS_VERIFIED, + self::STATUS_REJECTED => DraftInterface::STATUS_REJECTED, + ], + 'required' => false, + ] + ); + } +} diff --git a/OpenMarketplace/src/Component/Core/Admin/Form/Type/SettlementStatusFilterType.php b/OpenMarketplace/src/Component/Core/Admin/Form/Type/SettlementStatusFilterType.php new file mode 100644 index 0000000..88a8344 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Form/Type/SettlementStatusFilterType.php @@ -0,0 +1,34 @@ +add( + 'status', + ChoiceType::class, + [ + 'label' => false, + 'choices' => SettlementInterface::AVAILABLE_STATUSES, + 'choice_label' => fn (string $status) => sprintf('open_marketplace.ui.settlement_status.%s', $status), + 'required' => false, + ] + ); + } +} diff --git a/OpenMarketplace/src/Component/Core/Admin/Form/Type/VendorType.php b/OpenMarketplace/src/Component/Core/Admin/Form/Type/VendorType.php new file mode 100644 index 0000000..2c2dd0e --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Form/Type/VendorType.php @@ -0,0 +1,62 @@ +add('companyName', TextType::class, [ + 'label' => 'open_marketplace.ui.company_name', + ]) + ->add('taxIdentifier', TextType::class, [ + 'label' => 'open_marketplace.ui.tax_identifier', + ]) + ->add('bankAccountNumber', TextType::class, [ + 'label' => 'open_marketplace.ui.bank_account_number', + ]) + ->add('phoneNumber', TextType::class, [ + 'label' => 'open_marketplace.ui.phone_number', + ]) + ->add('vendorAddress', VendorAddressType::class, [ + 'label' => 'open_marketplace.ui.vendor_address', + ]) + ->add('commission', NumberType::class, [ + 'label' => 'open_marketplace.ui.commission', + ]) + ->add('commissionType', ChoiceType::class, [ + 'label' => 'open_marketplace.ui.commission_type', + 'choices' => [ + 'Net' => VendorInterface::NET_COMMISSION, + 'Gross' => VendorInterface::GROSS_COMMISSION, + ], + ]) + ->add('settlementFrequency', ChoiceType::class, [ + 'label' => 'open_marketplace.ui.settlement_frequency', + 'choices' => VendorSettlementFrequency::SETTLEMENT_FREQUENCIES, + 'choice_label' => function (string $frequency): string { + return sprintf('open_marketplace.ui.%s', $frequency); + }, + ]) + ; + } +} diff --git a/OpenMarketplace/src/Component/Core/Admin/Grid/Filter/ProductListingStatusFilter.php b/OpenMarketplace/src/Component/Core/Admin/Grid/Filter/ProductListingStatusFilter.php new file mode 100644 index 0000000..fa39a89 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Grid/Filter/ProductListingStatusFilter.php @@ -0,0 +1,29 @@ +restrict($dataSource->getExpressionBuilder()->equals('pd.status', $data['status'])); + } + } +} diff --git a/OpenMarketplace/src/Component/Core/Admin/Grid/Filter/SettlementPeriodFilter.php b/OpenMarketplace/src/Component/Core/Admin/Grid/Filter/SettlementPeriodFilter.php new file mode 100644 index 0000000..ab079f9 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Grid/Filter/SettlementPeriodFilter.php @@ -0,0 +1,54 @@ +formatDateForQuery($startDate); + $endDate = $this->formatDateForQuery($endDate); + + $dataSource->restrict( + $dataSource->getExpressionBuilder()->andX( + $dataSource->getExpressionBuilder()->equals( + 'startDate', + new \DateTime( + sprintf('%s 00:00:00', $startDate) + ) + ), + $dataSource->getExpressionBuilder()->equals( + 'endDate', + new \DateTime( + sprintf('%s 23:59:59', $endDate) + ) + ), + ) + ); + } + } + + private function formatDateForQuery(string $startDate): string + { + return implode('-', array_reverse(explode('/', $startDate))); + } +} diff --git a/OpenMarketplace/src/Component/Core/Admin/Grid/Filter/SettlementStatusFilter.php b/OpenMarketplace/src/Component/Core/Admin/Grid/Filter/SettlementStatusFilter.php new file mode 100644 index 0000000..19497b8 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Grid/Filter/SettlementStatusFilter.php @@ -0,0 +1,29 @@ +restrict($dataSource->getExpressionBuilder()->equals($name, $data[$name])); + } + } +} diff --git a/OpenMarketplace/src/Component/Core/Admin/MenuListener.php b/OpenMarketplace/src/Component/Core/Admin/MenuListener.php new file mode 100644 index 0000000..4d8a8d5 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/MenuListener.php @@ -0,0 +1,61 @@ +getMenu(); + + $mvmRootMenuItem = + $menu + ->addChild('marketplace') + ->setLabel('open_marketplace.ui.marketplace'); + + $mvmRootMenuItem + ->addChild('open_marketplace_product_listings', ['route' => 'open_marketplace_admin_product_listing_index']) + ->setLabel('open_marketplace.ui.product_listings') + ->setLabelAttribute('icon', 'list'); + + $mvmRootMenuItem + ->addChild('vendors', ['route' => 'open_marketplace_admin_vendor_index']) + ->setLabel('open_marketplace.ui.vendors') + ->setLabelAttribute('icon', 'users'); + + $mvmRootMenuItem + ->addChild('settlement', ['route' => 'open_marketplace_admin_settlement_index']) + ->setLabel('open_marketplace.ui.settlements') + ->setLabelAttribute('icon', 'money bill alternate'); + + $mvmRootMenuItem + ->addChild('virtual_wallet', ['route' => 'open_marketplace_admin_virtual_wallet_index']) + ->setLabel('open_marketplace.ui.virtual_wallets') + ->setLabelAttribute('icon', 'credit card'); + + $mvmRootMenuItem + ->addChild('conversations', ['route' => 'open_marketplace_admin_messaging_conversation_index']) + ->setLabel('open_marketplace.ui.menu.conversations') + ->setLabelAttribute('icon', 'inbox'); + + $mvmRootMenuItem + ->addChild('conversations_category', ['route' => 'open_marketplace_admin_messaging_conversation_category_index']) + ->setLabel('open_marketplace.ui.menu.conversation_categories') + ->setLabelAttribute('icon', 'inbox'); + + $manipulator = new MenuManipulator(); + $manipulator->moveChildToPosition($menu, $mvmRootMenuItem, 0); + } +} diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/config.yaml b/OpenMarketplace/src/Component/Core/Admin/Resources/config.yaml new file mode 100644 index 0000000..9a9bbf2 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/config.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: 'grids/*.yaml' } diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/grids/conversation.yaml b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/conversation.yaml new file mode 100755 index 0000000..7877b85 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/conversation.yaml @@ -0,0 +1,53 @@ +sylius_grid: + templates: + action: + archiveConversation: "Context/Admin/Conversation/_archiveConversation.html.twig" + grids: + open_marketplace_admin_messaging_conversation: + driver: + name: doctrine/orm + options: + class: "%open_marketplace.model.conversation.class%" + fields: + category: + type: twig + label: open_marketplace.ui.form.conversation.category + options: + template: 'Context/Admin/Conversation/_category.html.twig' + shopUser: + type: twig + label: open_marketplace.ui.grid.conversation.applicant + options: + template: 'Context/Admin/Conversation/_applicant.html.twig' + filters: + status: + label: open_marketplace.ui.status + type: select + form_options: + choices: + open_marketplace.ui.open: open + open_marketplace.ui.closed: closed + createdAt: + type: date + label: sylius.ui.date + options: + field: messages.createdAt + inclusive_to: true + actions: + main: + create: + type: create + options: + link: + route: open_marketplace_admin_messaging_conversation_create + item: + show: + type: show + options: + link: + route: open_marketplace_admin_messaging_conversation_show + delete: + type: delete + archive: + type: archiveConversation + label: open_marketplace.ui.grid.conversation.archive diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/grids/conversation_category.yaml b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/conversation_category.yaml new file mode 100644 index 0000000..f539cc2 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/conversation_category.yaml @@ -0,0 +1,19 @@ +sylius_grid: + grids: + conversation_category: + driver: + name: doctrine/orm + options: + class: "%open_marketplace.model.conversation_category.class%" + fields: + name: + type: string + actions: + main: + create: + type: create + item: + edit: + type: update + delete: + type: delete diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/grids/order.yaml b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/order.yaml new file mode 100644 index 0000000..51ca97d --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/order.yaml @@ -0,0 +1,8 @@ +sylius_grid: + grids: + sylius_admin_order: + driver: + options: + class: BitBag\OpenMarketplace\Component\Order\Entity\Order + repository: + method: findAllSecondaryOrdersQueryBuilder diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/grids/payment.yaml b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/payment.yaml new file mode 100644 index 0000000..5250640 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/payment.yaml @@ -0,0 +1,8 @@ +sylius_grid: + grids: + sylius_admin_payment: + driver: + options: + class: Sylius\Component\Core\Model\Payment + repository: + method: createSecondaryOrderPaymentQueryBuilder diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/grids/product_listing.yaml b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/product_listing.yaml new file mode 100644 index 0000000..0d4e126 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/product_listing.yaml @@ -0,0 +1,79 @@ +sylius_grid: + templates: + action: + details: 'Configuration/Grid/Admin/Action/productDetails.html.twig' + restore: 'Configuration/Grid/Admin/Action/restore.html.twig' + filter: + product_listing_status: 'Configuration/Grid/Admin/Filter/productListingStatus.html.twig' + grids: + open_marketplace_admin_product_listing: + driver: + name: doctrine/orm + options: + class: BitBag\OpenMarketplace\Component\ProductListing\Entity\Listing + repository: + method: createQueryBuilderWithLatestDraft + sorting: + id: desc + filters: + search: + type: string + form_options: + type: contains + options: + fields: ['code', 'vendor.companyName', 'vendor.shopUser.customer.firstName', 'vendor.shopUser.customer.lastName'] + vendor: + type: entity + label: open_marketplace.ui.vendor + form_options: + class: "BitBag\\OpenMarketplace\\Component\\Vendor\\Entity\\Vendor" + status: + type: product_listing_status + label: open_marketplace.ui.status + fields: + id: + type: string + label: open_marketplace.ui.id + sortable: ~ + code: + type: string + label: open_marketplace.ui.code + sortable: ~ + anyTranslationName: + type: twig + label: sylius.ui.name + sortable: latestDraft.translations.name + options: + template: "Configuration/Grid/Admin/Field/productListingName.html.twig" + vendor: + type: twig + label: open_marketplace.ui.vendor + sortable: vendor.companyName + options: + template: "Configuration/Grid/Admin/Field/productListingVendor.html.twig" + publishedAt: + type: datetime + label: open_marketplace.ui.published_at + sortable: ~ + lastVerifiedAt: + type: datetime + label: open_marketplace.ui.verified_at + sortable: ~ + verificationStatus: + type: twig + label: open_marketplace.ui.status + sortable: ~ + options: + template: "Configuration/Grid/Common/Field/productListingStatus.html.twig" + actions: + item: + details: + type: details + label: open_marketplace.ui.details + options: + link: + route: open_marketplace_admin_product_listing_show + parameters: + id: resource.id + restore_visibility: + type: restore diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/grids/settlement.yaml b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/settlement.yaml new file mode 100644 index 0000000..778f93a --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/settlement.yaml @@ -0,0 +1,80 @@ +sylius_grid: + templates: + filter: + settlement_status: 'Configuration/Grid/Admin/Filter/settlementStatus.html.twig' + settlement_period: 'Configuration/Grid/Admin/Filter/settlementPeriod.html.twig' + grids: + open_marketplace_admin_settlement: + driver: + name: doctrine/orm + options: + class: '%open_marketplace.model.settlement.class%' + sorting: + id: asc + filters: + channel: + type: entities + label: sylius.ui.channel + form_options: + class: "%sylius.model.channel.class%" + options: + field: "channel.id" + vendor: + type: entity + label: open_marketplace.ui.vendor + form_options: + class: "BitBag\\OpenMarketplace\\Component\\Vendor\\Entity\\Vendor" + status: + type: settlement_status + label: open_marketplace.ui.status + fields: + id: + type: string + sortable: ~ + label: open_marketplace.ui.id + vendor: + type: string + label: open_marketplace.ui.vendor + channel: + type: twig + label: sylius.ui.channel + sortable: channel.code + options: + template: "@SyliusAdmin/Order/Grid/Field/channel.html.twig" + totalAmount: + type: twig + label: open_marketplace.ui.total_amount + path: . + options: + template: "Configuration/Grid/Admin/Field/settlementTotals.html.twig" + vars: + method: getTotalAmount + totalCommissionAmount: + type: twig + label: open_marketplace.ui.total_commission_amount + path: . + options: + template: "Configuration/Grid/Admin/Field/settlementTotals.html.twig" + vars: + method: getTotalCommissionAmount + status: + type: twig + label: open_marketplace.ui.status + options: + template: "Configuration/Grid/Admin/Field/settlementStatus.html.twig" + period: + type: twig + label: open_marketplace.ui.period + path: . + options: + template: "Configuration/Grid/Admin/Field/settlementPeriod.html.twig" + actions: + item: + details: + type: details + label: open_marketplace.ui.details + options: + link: + route: open_marketplace_admin_settlement_show + parameters: + id: resource.id diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/grids/settlement_order.yaml b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/settlement_order.yaml new file mode 100644 index 0000000..c9a237c --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/settlement_order.yaml @@ -0,0 +1,75 @@ +sylius_grid: + grids: + open_marketplace_admin_settlement_order: + driver: + options: + class: BitBag\OpenMarketplace\Component\Order\Entity\Order + repository: + method: findForSettlementQueryBuilder + arguments: + settlement: expr:service('open_marketplace.repository.settlement').find(service('request_stack').getCurrentRequest().get('id')) + sorting: + number: desc + fields: + date: + type: datetime + label: sylius.ui.date + path: checkoutCompletedAt + sortable: checkoutCompletedAt + options: + format: d-m-Y H:i:s + number: + type: twig + label: sylius.ui.number + path: . + sortable: ~ + options: + template: "@SyliusAdmin/Order/Grid/Field/number.html.twig" + customer: + type: twig + label: sylius.ui.customer + sortable: customer.lastName + options: + template: "@SyliusAdmin/Order/Grid/Field/customer.html.twig" + total: + type: twig + label: sylius.ui.total + path: . + sortable: total + options: + template: "@SyliusAdmin/Order/Grid/Field/total.html.twig" + currencyCode: + type: string + label: sylius.ui.currency + sortable: ~ + filters: + number: + type: string + label: sylius.ui.number + customer: + type: string + label: sylius.ui.customer + options: + fields: [customer.email, customer.firstName, customer.lastName] + date: + type: date + label: sylius.ui.date + options: + field: checkoutCompletedAt + inclusive_to: true + total: + type: money + label: sylius.ui.total + options: + currency_field: currencyCode + shipping_method: + type: entity + label: sylius.ui.shipping_method + options: + fields: [shipments.method] + form_options: + class: "%sylius.model.shipping_method.class%" + actions: + item: + show: + type: show diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/grids/shipment.yaml b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/shipment.yaml new file mode 100644 index 0000000..a19d6c1 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/shipment.yaml @@ -0,0 +1,8 @@ +sylius_grid: + grids: + sylius_admin_shipment: + driver: + options: + class: BitBag\OpenMarketplace\Component\Order\Entity\Shipment + repository: + method: createNonPrimaryQueryBuilder diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/grids/vendor.yaml b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/vendor.yaml new file mode 100644 index 0000000..5f29f62 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/vendor.yaml @@ -0,0 +1,55 @@ +sylius_grid: + templates: + action: + enable_vendor_action: "Configuration/Grid/Admin/Action/enableVendor.html.twig" + edit_vendor: "Configuration/Grid/Admin/Action/editVendor.html.twig" + show_product_listings: "Configuration/Grid/Admin/Action/showVendorProductListings.html.twig" + show_settlements: "Configuration/Grid/Admin/Action/showVendorSettlements.html.twig" + show_virtual_wallets: "Configuration/Grid/Admin/Action/showVendorVirtualWallets.html.twig" + grids: + open_marketplace_admin_vendor: + driver: + name: doctrine/orm + options: + class: '%open_marketplace.model.vendor.class%' + sorting: + id: asc + fields: + id: + type: string + label: open_marketplace.ui.id + sortable: ~ + companyName: + type: string + label: open_marketplace.ui.company_name + sortable: ~ + taxIdentifier: + type: string + label: open_marketplace.ui.tax_id + sortable: ~ + status: + type: twig + label: open_marketplace.ui.status + options: + template: 'Configuration/Grid/Admin/Field/status.html.twig' + sortable: ~ + enabled: + type: twig + label: open_marketplace.ui.enabled + options: + template: 'Configuration/Grid/Admin/Field/enabled.html.twig' + actions: + item: + details: + label: open_marketplace.ui.details + type: show + update: + type: edit_vendor + enable_disable: + type: enable_vendor_action + show_product_listings: + type: show_product_listings + show_settlements: + type: show_settlements + show_virtual_wallets: + type: show_virtual_wallets diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/grids/virtual_wallet.yaml b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/virtual_wallet.yaml new file mode 100644 index 0000000..f2688ed --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/grids/virtual_wallet.yaml @@ -0,0 +1,42 @@ +sylius_grid: + grids: + open_marketplace_admin_virtual_wallet: + driver: + name: doctrine/orm + options: + class: '%open_marketplace.model.virtual_wallet.class%' + sorting: + vendor: asc + filters: + channel: + type: entities + label: sylius.ui.channel + form_options: + class: "%sylius.model.channel.class%" + options: + field: "channel.id" + vendor: + type: entity + label: open_marketplace.ui.vendor + form_options: + class: "BitBag\\OpenMarketplace\\Component\\Vendor\\Entity\\Vendor" + fields: + vendor: + type: string + label: open_marketplace.ui.vendor + sortable: vendor.id + channel: + type: twig + label: sylius.ui.channel + sortable: channel.code + options: + template: "@SyliusAdmin/Order/Grid/Field/channel.html.twig" + balance: + type: twig + label: open_marketplace.ui.balance + path: . + sortable: ~ + options: + template: "Configuration/Grid/Admin/Field/money.html.twig" + vars: + method: getBalance diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/routing.yaml b/OpenMarketplace/src/Component/Core/Admin/Resources/routing.yaml new file mode 100644 index 0000000..5f964f0 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/routing.yaml @@ -0,0 +1,14 @@ +open_marketplace_admin_resources: + resource: "routing/resources.yaml" + +open_marketplace_admin_messaging: + resource: "routing/messaging.yaml" + +open_marketplace_admin_product_listing: + resource: "routing/product_listing.yaml" + +open_marketplace_admin_vendor: + resource: "routing/vendor.yaml" + +open_marketplace_admin_settlement: + resource: "routing/settlement.yaml" diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/routing/messaging.yaml b/OpenMarketplace/src/Component/Core/Admin/Resources/routing/messaging.yaml new file mode 100644 index 0000000..6331938 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/routing/messaging.yaml @@ -0,0 +1,46 @@ +open_marketplace_admin_messaging_conversation_index: + path: /conversations + methods: [GET] + defaults: + _controller: open_marketplace.controller.conversation:index + +open_marketplace_admin_messaging_conversation_create: + path: /conversation/create + methods: [GET,POST] + defaults: + _controller: bitbag.open_marketplace.component.core.common.controller.messaging.create_thread + _sylius: + template: "Context/Admin/Conversation/create.html.twig" + redirect: open_marketplace_admin_messaging_conversation_show + mail_redirect: mvm_vendor_conversation_show + +open_marketplace_admin_messaging_conversation_show: + path: /conversations/{id} + methods: [GET,POST] + defaults: + _controller: bitbag.open_marketplace.component.core.common.controller.messaging.show_thread + _sylius: + template: "Context/Admin/Conversation/show.html.twig" + +open_marketplace_admin_messaging_conversation_archive: + path: /conversations/{id}/archive + methods: [GET,POST] + defaults: + _controller: bitbag.open_marketplace.component.core.admin.controller.messaging.send_archive_request + _sylius: + redirect: open_marketplace_admin_messaging_conversation_index + +open_marketplace_admin_messaging_conversation_message_add: + path: /conversations/{id}/message/add + methods: [GET, POST] + defaults: + _controller: bitbag.open_marketplace.component.core.common.controller.messaging.create_message + _sylius: + redirect: open_marketplace_admin_messaging_conversation_show + mail_redirect: open_marketplace_admin_messaging_conversation_show + +open_marketplace_admin_messaging_conversation_category_index: + path: /conversation-categories + methods: [GET] + defaults: + _controller: open_marketplace.controller.conversation_category:index diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/routing/product_listing.yaml b/OpenMarketplace/src/Component/Core/Admin/Resources/routing/product_listing.yaml new file mode 100644 index 0000000..84e243b --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/routing/product_listing.yaml @@ -0,0 +1,32 @@ +open_marketplace_admin_product_listing_show: + path: /product-listings/{id} + defaults: + _controller: bitbag.open_marketplace.component.core.admin.controller.product_listing.show + _sylius: + section: admin + template: "Context/Admin/ProductListing/show.html.twig" + permission: true + +open_marketplace_admin_product_listing_accept: + path: /product-listings/{id}/accept + defaults: + _controller: bitbag.open_marketplace.component.core.admin.controller.product_listing.accept + _sylius: + section: admin + permission: true + +open_marketplace_admin_product_listing_reject: + path: /product-listings/{id}/reject + defaults: + _controller: bitbag.open_marketplace.component.core.admin.controller.product_listing.reject + _sylius: + section: admin + permission: true + +open_marketplace_admin_product_listing_restore: + path: /product-listings/{id}/restore + defaults: + _controller: bitbag.open_marketplace.component.core.admin.controller.product_listing.restore + _sylius: + section: admin + permission: true diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/routing/resources.yaml b/OpenMarketplace/src/Component/Core/Admin/Resources/routing/resources.yaml new file mode 100644 index 0000000..9474268 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/routing/resources.yaml @@ -0,0 +1,61 @@ +open_marketplace_admin_resource_conversation: + resource: | + alias: open_marketplace.conversation + section: admin + templates: "@SyliusAdmin\\Crud" + except: ['show', 'update', 'bulk_delete'] + redirect: index + grid: open_marketplace_admin_messaging_conversation + permission: true + vars: + all: + header: open_marketplace.ui.conversations_listing.admin_header + subheader: open_marketplace.ui.conversations_listing.admin_subheader + type: sylius.resource + +open_marketplace_admin_resource_conversation_category: + resource: | + alias: open_marketplace.conversation_category + section: admin + except: ['show'] + templates: "@SyliusAdmin\\Crud" + grid: conversation_category + type: sylius.resource + +open_marketplace_admin_resource_product_listing: + resource: | + alias: open_marketplace.product_listing + section: admin + templates: '@SyliusAdmin/Crud' + only: ['index'] + redirect: index + grid: open_marketplace_admin_product_listing + type: sylius.resource + +open_marketplace_admin_resource_vendor: + resource: | + alias: open_marketplace.vendor + section: admin + except: ['show'] + templates: "@SyliusAdmin\\Crud" + grid: open_marketplace_admin_vendor + type: sylius.resource + +open_marketplace_admin_resource_settlement: + resource: | + alias: open_marketplace.settlement + section: admin + only: ['index', 'show'] + templates: "@SyliusAdmin\\Crud" + grid: open_marketplace_admin_settlement + type: sylius.resource + +open_marketplace_admin_resource_virtual_wallet: + resource: | + alias: open_marketplace.virtual_wallet + section: admin + only: ['index'] + templates: "@SyliusAdmin\\Crud" + grid: open_marketplace_admin_virtual_wallet + type: sylius.resource + diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/routing/settlement.yaml b/OpenMarketplace/src/Component/Core/Admin/Resources/routing/settlement.yaml new file mode 100644 index 0000000..9107d3e --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/routing/settlement.yaml @@ -0,0 +1,19 @@ +open_marketplace_admin_settlement_show: + path: /settlement/{id} + defaults: + _controller: open_marketplace.controller.settlement:showAction + _sylius: + section: admin + template: 'Context/Admin/Settlement/show.html.twig' + permission: true + +open_marketplace_admin_settlements_show_orders: + path: /settlement/{id}/orders + methods: [GET] + defaults: + _controller: open_marketplace.controller.settlement:showOrderAction + _sylius: + section: admin + permission: true + template: 'Context/Admin/Settlement/showOrders.html.twig' + grid: open_marketplace_admin_settlement_order diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/routing/vendor.yaml b/OpenMarketplace/src/Component/Core/Admin/Resources/routing/vendor.yaml new file mode 100644 index 0000000..47c3945 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/routing/vendor.yaml @@ -0,0 +1,35 @@ +open_marketplace_admin_vendor_show: + path: /vendors/{id} + methods: [GET] + defaults: + _controller: open_marketplace.controller.vendor:showAction + _sylius: + section: admin + permission: true + template: 'Context/Admin/Vendor/show.html.twig' + +open_marketplace_admin_vendor_update: + path: /vendors/{id}/edit + methods: [GET, PUT] + defaults: + _controller: open_marketplace.controller.vendor:updateAction + _sylius: + section: admin + permission: true + template: 'Context/Admin/Vendor/update.html.twig' + +open_marketplace_admin_vendor_disable: + path: /vendors/{id}/disable + methods: [PUT] + controller: bitbag.open_marketplace.component.core.common.controller.resource.vendor:enablingVendorAction + +open_marketplace_admin_vendor_verify: + path: /vendors/{id}/verify + methods: [PUT] + controller: bitbag.open_marketplace.component.core.common.controller.resource.vendor:verifyVendorAction + +open_marketplace_admin_vendor_enable: + path: /vendors/{id}/enable + methods: [PUT] + controller: bitbag.open_marketplace.component.core.common.controller.resource.vendor:enablingVendorAction + diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/services.xml b/OpenMarketplace/src/Component/Core/Admin/Resources/services.xml new file mode 100644 index 0000000..a572675 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/services.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/services/controllers.xml b/OpenMarketplace/src/Component/Core/Admin/Resources/services/controllers.xml new file mode 100644 index 0000000..b11eba0 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/services/controllers.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/services/filters.xml b/OpenMarketplace/src/Component/Core/Admin/Resources/services/filters.xml new file mode 100644 index 0000000..98f2232 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/services/filters.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Admin/Resources/services/form_types.xml b/OpenMarketplace/src/Component/Core/Admin/Resources/services/form_types.xml new file mode 100644 index 0000000..387dca0 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Admin/Resources/services/form_types.xml @@ -0,0 +1,21 @@ + + + + + + + + + + BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Context/VendorContext.php b/OpenMarketplace/src/Component/Core/Api/Context/VendorContext.php new file mode 100644 index 0000000..1cd54d6 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Context/VendorContext.php @@ -0,0 +1,35 @@ +userContext->getUser(); + + if (!$shopUser instanceof ShopUserInterface) { + return null; + } + + return $shopUser->getVendor(); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Context/VendorContextInterface.php b/OpenMarketplace/src/Component/Core/Api/Context/VendorContextInterface.php new file mode 100644 index 0000000..ed28113 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Context/VendorContextInterface.php @@ -0,0 +1,19 @@ +isConversationReportedToArchive()) { + $data->setStatus(Conversation::STATUS_CLOSED); + + $this->entityManager->persist($data); + $this->entityManager->flush(); + + return $data; + } + + return new Response('', Response::HTTP_BAD_REQUEST); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Controller/Vendor/DeleteProductListingAction.php b/OpenMarketplace/src/Component/Core/Api/Controller/Vendor/DeleteProductListingAction.php new file mode 100644 index 0000000..87faf9c --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Controller/Vendor/DeleteProductListingAction.php @@ -0,0 +1,39 @@ +remove(); + + if (null !== $product = $data->getProduct()) { + $product->setEnabled(false); + $this->entityManager->persist($product); + } + + $this->entityManager->persist($data); + $this->entityManager->flush(); + + return new JsonResponse(null, Response::HTTP_NO_CONTENT); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Controller/Vendor/SendToVerificationAction.php b/OpenMarketplace/src/Component/Core/Api/Controller/Vendor/SendToVerificationAction.php new file mode 100644 index 0000000..8fe6eb2 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Controller/Vendor/SendToVerificationAction.php @@ -0,0 +1,38 @@ +canBeVerified()) { + /** @var DraftInterface $latestDraft */ + $latestDraft = $data->getLatestDraft(); + Assert::notNull($latestDraft); + + $this->productDraftStateMachineTransition->applyIfCan($latestDraft, DraftTransitions::TRANSITION_SEND_TO_VERIFICATION); + } + + return $data; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/DataPersister/ConversationPersister.php b/OpenMarketplace/src/Component/Core/Api/DataPersister/ConversationPersister.php new file mode 100644 index 0000000..15aae16 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/DataPersister/ConversationPersister.php @@ -0,0 +1,44 @@ +setShopUser($this->security->getUser()); + + $this->manager->persist($data); + $this->manager->flush(); + } + + public function remove($data): void + { + $this->manager->remove($data); + $this->manager->flush(); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/DataPersister/MessagePersister.php b/OpenMarketplace/src/Component/Core/Api/DataPersister/MessagePersister.php new file mode 100644 index 0000000..3421fc3 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/DataPersister/MessagePersister.php @@ -0,0 +1,44 @@ +setShopUser($this->security->getUser()); + + $this->manager->persist($data); + $this->manager->flush(); + } + + public function remove($data): void + { + $this->manager->remove($data); + $this->manager->flush(); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/DataProvider/CustomerItemDataProvider.php b/OpenMarketplace/src/Component/Core/Api/DataProvider/CustomerItemDataProvider.php new file mode 100644 index 0000000..2877b5f --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/DataProvider/CustomerItemDataProvider.php @@ -0,0 +1,54 @@ +sectionProvider->getSection(); + $vendor = $this->vendorContext->getVendor(); + if (null !== $vendor && $section instanceof ShopVendorApiSection) { + /** @phpstan-ignore-next-line function strval() is risky */ + return $this->customerRepository->findCustomerForVendor($vendor, (string) $id); + } + + return $this->baseCustomerItemDataProvider->getItem($resourceClass, $id, $operationName, $context); + } + + public function supports( + string $resourceClass, + string $operationName = null, + array $context = [] + ): bool { + /** @phpstan-ignore-next-line BaseCustomerItemDataProvider doesn't have interface */ + return $this->baseCustomerItemDataProvider->supports($resourceClass, $operationName, $context); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/DataProvider/VendorAccountItemDataProvider.php b/OpenMarketplace/src/Component/Core/Api/DataProvider/VendorAccountItemDataProvider.php new file mode 100644 index 0000000..b069fd1 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/DataProvider/VendorAccountItemDataProvider.php @@ -0,0 +1,76 @@ +sectionProvider->getSection(); + + if (($section instanceof AdminApiSection) || + ($section instanceof ShopVendorApiSection && $this->isRequestedByRightVendor($id)) || + ($section instanceof ShopApiSection) + ) { + return $this->vendorRepository->findOneBy(['uuid' => $id]); + } + + return null; + } + + public function supports( + string $resourceClass, + string $operationName = null, + array $context = [] + ): bool { + return is_a($resourceClass, VendorInterface::class, true); + } + + public function isRequestedByRightVendor(UuidInterface $uuid): bool + { + $vendor = $this->vendorContext->getVendor(); + + if (null === $vendor) { + return false; + } + + /** @var UuidInterface $userVendorUuid */ + $userVendorUuid = $vendor->getUuid(); + + return $uuid->equals($userVendorUuid); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/DataTransformer/ProductDraftAwareCommandDataTransformer.php b/OpenMarketplace/src/Component/Core/Api/DataTransformer/ProductDraftAwareCommandDataTransformer.php new file mode 100644 index 0000000..aba403e --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/DataTransformer/ProductDraftAwareCommandDataTransformer.php @@ -0,0 +1,74 @@ +getProductDraft()) { + return $object; + } + + /** @var Request $request */ + $request = $this->requestStack->getCurrentRequest(); + + $files = $request->files; + + if (null === $imageFiles = $files->get('images')) { + return $object; + } + + if (!is_array($imageFiles)) { + return $object; + } + + $productDraft->getImages()->clear(); + + foreach ($imageFiles as $imageFile) { + if ($imageFile instanceof UploadedFile) { + $draftImage = $this->draftImageFactory->createNew(); + $draftImage->setFile($imageFile); + $productDraft->addImage($draftImage); + } + } + + return $object; + } + + /** @param object $object */ + public function supportsTransformation($object): bool + { + return $object instanceof ProductDraftAwareInterface; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/DataTransformer/ProductListingAwareCommandDataTransformer.php b/OpenMarketplace/src/Component/Core/Api/DataTransformer/ProductListingAwareCommandDataTransformer.php new file mode 100644 index 0000000..6f7700e --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/DataTransformer/ProductListingAwareCommandDataTransformer.php @@ -0,0 +1,44 @@ +getProductListing()) { + return $object; + } + + $productListing = $context['object_to_populate']; + $object->setProductListing($productListing); + + return $object; + } + + /** @param object $object */ + public function supportsTransformation($object): bool + { + return $object instanceof ProductListingAwareInterface; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/DataTransformer/ResourceIdAwareCommandDataTransformer.php b/OpenMarketplace/src/Component/Core/Api/DataTransformer/ResourceIdAwareCommandDataTransformer.php new file mode 100644 index 0000000..43ffed7 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/DataTransformer/ResourceIdAwareCommandDataTransformer.php @@ -0,0 +1,57 @@ +requestStack->getCurrentRequest(); + $attributes = $request->attributes; + + $attributeKey = $object->getResourceIdAttributeKey(); + Assert::true($attributes->has($attributeKey), 'Path does not have resource id'); + + /** @var string $resourceId */ + $resourceId = $attributes->get($object->getResourceIdAttributeKey()); + + $object->setResourceId($resourceId); + + return $object; + } + + /** @param ResourceIdAwareInterface $object */ + public function supportsTransformation($object): bool + { + return $object instanceof ResourceIdAwareInterface; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/DataTransformer/ShopUserAwareInputCommandDataTransformer.php b/OpenMarketplace/src/Component/Core/Api/DataTransformer/ShopUserAwareInputCommandDataTransformer.php new file mode 100644 index 0000000..6a10ef0 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/DataTransformer/ShopUserAwareInputCommandDataTransformer.php @@ -0,0 +1,55 @@ +getShopUser()) { + return $object; + } + + $user = $this->userContext->getUser(); + if ($user instanceof ShopUserInterface) { + $object->setShopUser($user); + } + + return $object; + } + + /** + * @param ShopUserAwareInterface $object + */ + public function supportsTransformation($object): bool + { + return $object instanceof ShopUserAwareInterface; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/DataTransformer/VendorImageFileAwareCommandDataTransformer.php b/OpenMarketplace/src/Component/Core/Api/DataTransformer/VendorImageFileAwareCommandDataTransformer.php new file mode 100644 index 0000000..8f437ab --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/DataTransformer/VendorImageFileAwareCommandDataTransformer.php @@ -0,0 +1,58 @@ +requestStack->getCurrentRequest(); + + $files = $request->files; + + if (null === $file = $files->get('file')) { + return $object; + } + + if ($file instanceof UploadedFile) { + $object->setFile($file); + } + + return $object; + } + + /** @param object $object */ + public function supportsTransformation($object): bool + { + return $object instanceof VendorImageFileAwareInterface; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/DataTransformer/VendorImageOwnerAwareCommandDataTransformer.php b/OpenMarketplace/src/Component/Core/Api/DataTransformer/VendorImageOwnerAwareCommandDataTransformer.php new file mode 100644 index 0000000..e8da349 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/DataTransformer/VendorImageOwnerAwareCommandDataTransformer.php @@ -0,0 +1,57 @@ +getOwner()) { + return $object; + } + + $shopUser = $this->userContext->getUser(); + if (!$shopUser instanceof ShopUserInterface) { + return $object; + } + + if (null !== $vendor = $shopUser->getVendor()) { + $object->setOwner($vendor); + } + + return $object; + } + + /** @param object $object */ + public function supportsTransformation($object): bool + { + return $object instanceof VendorImageOwnerAwareInterface; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryCollectionExtension/OrdersByLoggedInUserExtension.php b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryCollectionExtension/OrdersByLoggedInUserExtension.php new file mode 100644 index 0000000..388e5de --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryCollectionExtension/OrdersByLoggedInUserExtension.php @@ -0,0 +1,63 @@ +sectionProvider->getSection() instanceof ShopVendorApiSection) { + return; + } + + if ($this->userContext->getUser() instanceof ShopUserInterface) { + $rootAlias = $queryBuilder->getRootAliases()[0]; + $queryBuilder + ->andWhere(sprintf('%s.mode != :primaryMode', $rootAlias)) + ->setParameter('primaryMode', MarketplaceOrderInterface::PRIMARY_ORDER_MODE) + ; + } + + $this->baseOrdersByLoggedInUserExtension->applyToCollection( + $queryBuilder, + $queryNameGenerator, + $resourceClass, + $operationName, + $context + ); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextExtension.php b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextExtension.php new file mode 100644 index 0000000..d360328 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextExtension.php @@ -0,0 +1,92 @@ +filterVendorStrategies = $filterVendorStrategies instanceof \Traversable + ? iterator_to_array($filterVendorStrategies) + : $filterVendorStrategies; + } + + public function applyToCollection( + QueryBuilder $queryBuilder, + QueryNameGeneratorInterface $queryNameGenerator, + string $resourceClass, + Operation $operation = null, + array $context = [] + ): void { + $this->filterByVendorIfApply($queryBuilder, $resourceClass); + } + + public function applyToItem( + QueryBuilder $queryBuilder, + QueryNameGeneratorInterface $queryNameGenerator, + string $resourceClass, + array $identifiers, + Operation $operation = null, + array $context = [] + ): void { + if (Conversation::class === $resourceClass) { + return; + } + $this->filterByVendorIfApply($queryBuilder, $resourceClass); + } + + public function filterByVendorIfApply(QueryBuilder $queryBuilder, string $resourceClass): void + { + if (null === $filterVendorStrategy = $this->getSupportedStrategy($resourceClass)) { + return; + } + + if (false === $this->uriBasedSectionContext->getSection() instanceof ShopVendorApiSection) { + return; + } + + if (null === $vendor = $this->vendorContext->getVendor()) { + $this->filterForEmptyResult($queryBuilder); + } else { + $filterVendorStrategy->filterByVendor($queryBuilder, $vendor); + } + } + + private function filterForEmptyResult(QueryBuilder $queryBuilder): void + { + $queryBuilder->andWhere('1=0'); + } + + private function getSupportedStrategy(string $class): ?FilterVendorStrategy + { + /** @var FilterVendorStrategy $filterVendorStrategy */ + foreach ($this->filterVendorStrategies as $filterVendorStrategy) { + if ($filterVendorStrategy->supports($class)) { + return $filterVendorStrategy; + } + } + + return null; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/AbstractFilterStrategy.php b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/AbstractFilterStrategy.php new file mode 100644 index 0000000..2db03ee --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/AbstractFilterStrategy.php @@ -0,0 +1,27 @@ +getSupportedClasses() as $supportedClass) { + if (is_a($class, $supportedClass, true)) { + return true; + } + } + + return false; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/ConversationFilterStrategy.php b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/ConversationFilterStrategy.php new file mode 100644 index 0000000..44293a1 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/ConversationFilterStrategy.php @@ -0,0 +1,32 @@ +getRootAliases()[0]; + $queryBuilder->andWhere(sprintf('%s.shopUser', $rootAlias) . ' = :currentShopUser'); + $queryBuilder->setParameter('currentShopUser', $vendor->getShopUser()); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/CustomerFilterStrategy.php b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/CustomerFilterStrategy.php new file mode 100644 index 0000000..c1de18c --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/CustomerFilterStrategy.php @@ -0,0 +1,33 @@ +getRootAliases()[0]; + $queryBuilder->innerJoin(sprintf('%s.orders', $rootAlias), 'orders'); + $queryBuilder->andWhere('orders.vendor = :currentVendor'); + $queryBuilder->setParameter('currentVendor', $vendor->getId()); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/FilterVendorStrategy.php b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/FilterVendorStrategy.php new file mode 100644 index 0000000..434739b --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/FilterVendorStrategy.php @@ -0,0 +1,21 @@ +getRootAliases()[0]; + $queryBuilder->innerJoin(sprintf('%s.productListing', $rootAlias), 'p'); + $queryBuilder->andWhere('p.vendor = :currentVendor'); + $queryBuilder->setParameter('currentVendor', $vendor->getId()); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/ProductVariantFilterStrategy.php b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/ProductVariantFilterStrategy.php new file mode 100644 index 0000000..bb1b108 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/ProductVariantFilterStrategy.php @@ -0,0 +1,33 @@ +getRootAliases()[0]; + $queryBuilder->innerJoin(sprintf('%s.product', $rootAlias), 'p'); + $queryBuilder->andWhere('p.vendor = :currentVendor'); + $queryBuilder->setParameter('currentVendor', $vendor->getId()); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/VendorFilterStrategy.php b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/VendorFilterStrategy.php new file mode 100644 index 0000000..ff5eb2b --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/VendorFilterStrategy.php @@ -0,0 +1,35 @@ +getRootAliases()[0]; + $queryBuilder + ->andWhere(sprintf('%s.vendor = :account_vendor', $rootAlias)) + ->setParameter('account_vendor', $vendor); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryItemExtension/OrderGetMethodItemExtension.php b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryItemExtension/OrderGetMethodItemExtension.php new file mode 100644 index 0000000..010e1d8 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryItemExtension/OrderGetMethodItemExtension.php @@ -0,0 +1,64 @@ +sectionProvider->getSection() instanceof ShopVendorApiSection) { + return; + } + + if ($this->userContext->getUser() instanceof ShopUserInterface) { + $rootAlias = $queryBuilder->getRootAliases()[0]; + $queryBuilder + ->andWhere(sprintf('%s.mode != :primaryMode', $rootAlias)) + ->setParameter('primaryMode', \BitBag\OpenMarketplace\Component\Order\Entity\OrderInterface::PRIMARY_ORDER_MODE) + ; + } + + $this->baseOrderGetMethodItemExtension->applyToItem( + $queryBuilder, + $queryNameGenerator, + $resourceClass, + $identifiers, + $operationName, + $context + ); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryItemExtension/OrderMethodsItemExtension.php b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryItemExtension/OrderMethodsItemExtension.php new file mode 100644 index 0000000..454316e --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Doctrine/QueryItemExtension/OrderMethodsItemExtension.php @@ -0,0 +1,65 @@ +sectionProvider->getSection() instanceof ShopVendorApiSection) { + return; + } + + if ($this->userContext->getUser() instanceof ShopUserInterface) { + $rootAlias = $queryBuilder->getRootAliases()[0]; + + $queryBuilder + ->andWhere(sprintf('%s.mode != :primaryMode', $rootAlias)) + ->setParameter('primaryMode', \BitBag\OpenMarketplace\Component\Order\Entity\OrderInterface::PRIMARY_ORDER_MODE) + ; + } + + $this->baseOrderMethodsItemExtension->applyToItem( + $queryBuilder, + $queryNameGenerator, + $resourceClass, + $identifiers, + $operationName, + $context + ); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/EventSubscriber/UuidSubscriber.php b/OpenMarketplace/src/Component/Core/Api/EventSubscriber/UuidSubscriber.php new file mode 100644 index 0000000..3eace82 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/EventSubscriber/UuidSubscriber.php @@ -0,0 +1,61 @@ +updateUuid($event); + } + + public function preUpdate(LifecycleEventArgs $event): void + { + $this->updateUuid($event); + } + + public function updateUuid(LifecycleEventArgs $event): void + { + /** @var object $object */ + $object = $event->getObject(); + + if (!$object instanceof UuidAwareInterface) { + return; + } + + if (null === $object->getUuid()) { + /** @var EntityManager $em */ + $em = $event->getObjectManager(); + $uuid = $this->uuidGenerator->generate($em, $object); + $object->setUuid($uuid); + } + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/EventSubscriber/VendorAwareEventSubscriber.php b/OpenMarketplace/src/Component/Core/Api/EventSubscriber/VendorAwareEventSubscriber.php new file mode 100644 index 0000000..401b448 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/EventSubscriber/VendorAwareEventSubscriber.php @@ -0,0 +1,55 @@ + ['setVendorFromCurrentContext', EventPriorities::PRE_VALIDATE], + ]; + } + + public function setVendorFromCurrentContext(ViewEvent $event): void + { + $vendorAware = $event->getControllerResult(); + if (!$vendorAware instanceof VendorAwareInterface) { + return; + } + + $method = $event->getRequest()->getMethod(); + if (!in_array($method, [Request::METHOD_POST], true)) { + return; + } + + $vendor = $this->vendorContext->getVendor(); + if (null === $vendor) { + return; + } + + $vendorAware->setVendor($vendor); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/EventSubscriber/VendorSlugEventSubscriber.php b/OpenMarketplace/src/Component/Core/Api/EventSubscriber/VendorSlugEventSubscriber.php new file mode 100644 index 0000000..40950b4 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/EventSubscriber/VendorSlugEventSubscriber.php @@ -0,0 +1,58 @@ + ['generateSlug', EventPriorities::PRE_VALIDATE], + ]; + } + + public function generateSlug(ViewEvent $event): void + { + $vendorSlugAware = $event->getControllerResult(); + if (!$vendorSlugAware instanceof VendorInterface && + !$vendorSlugAware instanceof VendorSlugAwareInterface + ) { + return; + } + + if (empty($vendorSlugAware->getCompanyName())) { + return; + } + + $method = $event->getRequest()->getMethod(); + if (!in_array($method, [Request::METHOD_POST, Request::METHOD_PUT], true)) { + return; + } + + $slug = $this->vendorSlugGenerator->generateSlug($vendorSlugAware->getCompanyName()); + $vendorSlugAware->setSlug($slug); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Factory/ShopVendorApiSectionFactory.php b/OpenMarketplace/src/Component/Core/Api/Factory/ShopVendorApiSectionFactory.php new file mode 100644 index 0000000..ec34f01 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Factory/ShopVendorApiSectionFactory.php @@ -0,0 +1,21 @@ +productDraft; + } + + public function setProductDraft(Draft $productDraft): void + { + $this->productDraft = $productDraft; + } + + public function getVendor(): VendorInterface + { + return $this->vendor; + } + + public function setVendor(VendorInterface $vendor): void + { + $this->vendor = $vendor; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Messenger/Command/Vendor/CreateProductListingInterface.php b/OpenMarketplace/src/Component/Core/Api/Messenger/Command/Vendor/CreateProductListingInterface.php new file mode 100644 index 0000000..a6418f5 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Messenger/Command/Vendor/CreateProductListingInterface.php @@ -0,0 +1,18 @@ +companyName; + } + + public function getTaxIdentifier(): string + { + return $this->taxIdentifier; + } + + public function getBankAccountNumber(): string + { + return $this->bankAccountNumber; + } + + public function getPhoneNumber(): string + { + return $this->phoneNumber; + } + + public function getDescription(): string + { + return $this->description; + } + + public function getVendorAddress(): Address + { + return $this->vendorAddress; + } + + public function getSlug(): ?string + { + return $this->slug; + } + + public function setSlug(?string $slug): void + { + $this->slug = $slug; + } + + public function getShopUser(): ?ShopUserInterface + { + return $this->shopUser; + } + + public function setShopUser(?ShopUserInterface $shopUser): void + { + $this->shopUser = $shopUser; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Messenger/Command/Vendor/RegisterVendorInterface.php b/OpenMarketplace/src/Component/Core/Api/Messenger/Command/Vendor/RegisterVendorInterface.php new file mode 100644 index 0000000..a55648e --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Messenger/Command/Vendor/RegisterVendorInterface.php @@ -0,0 +1,31 @@ +productDraft; + } + + public function setProductDraft(Draft $productDraft): void + { + $this->productDraft = $productDraft; + } + + public function getVendor(): VendorInterface + { + return $this->vendor; + } + + public function setVendor(VendorInterface $vendor): void + { + $this->vendor = $vendor; + } + + public function getProductListing(): ?ListingInterface + { + return $this->productListing; + } + + public function setProductListing(ListingInterface $productListing): void + { + $this->productListing = $productListing; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Messenger/Command/Vendor/UpdateProductListingInterface.php b/OpenMarketplace/src/Component/Core/Api/Messenger/Command/Vendor/UpdateProductListingInterface.php new file mode 100644 index 0000000..4f1b619 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Messenger/Command/Vendor/UpdateProductListingInterface.php @@ -0,0 +1,18 @@ +file; + } + + public function setFile(?UploadedFile $file): void + { + $this->file = $file; + } + + public function getOwner(): ?VendorInterface + { + return $this->owner; + } + + public function setOwner(VendorInterface $owner): void + { + $this->owner = $owner; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Messenger/Command/Vendor/UploadVendorBackgroundImageInterface.php b/OpenMarketplace/src/Component/Core/Api/Messenger/Command/Vendor/UploadVendorBackgroundImageInterface.php new file mode 100644 index 0000000..703e3c3 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Messenger/Command/Vendor/UploadVendorBackgroundImageInterface.php @@ -0,0 +1,16 @@ +file; + } + + public function setFile(?UploadedFile $file): void + { + $this->file = $file; + } + + public function getOwner(): ?VendorInterface + { + return $this->owner; + } + + public function setOwner(VendorInterface $owner): void + { + $this->owner = $owner; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Messenger/Command/Vendor/UploadVendorImageInterface.php b/OpenMarketplace/src/Component/Core/Api/Messenger/Command/Vendor/UploadVendorImageInterface.php new file mode 100644 index 0000000..4d1de01 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Messenger/Command/Vendor/UploadVendorImageInterface.php @@ -0,0 +1,16 @@ +getProductDraft(); + $vendor = $createProductListing->getVendor(); + + $this->listingPersister->createNewProductListing($productDraft, $vendor); + $this->manager->persist($productDraft->getProductListing()); + + return $productDraft->getProductListing(); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Messenger/CommandHandler/Vendor/RegisterVendorHandler.php b/OpenMarketplace/src/Component/Core/Api/Messenger/CommandHandler/Vendor/RegisterVendorHandler.php new file mode 100644 index 0000000..ae5ae9b --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Messenger/CommandHandler/Vendor/RegisterVendorHandler.php @@ -0,0 +1,54 @@ +getShopUser()) { + throw new \DomainException('Shop user should be set'); + } + + if (!$command->getSlug()) { + throw new \DomainException('Slug should be set'); + } + + /** @var ShopUserInterface $shopUser */ + $shopUser = $command->getShopUser(); + $vendor = $this->vendorProvider->provide($shopUser); + + $vendor->setCompanyName($command->getCompanyName()); + $vendor->setTaxIdentifier($command->getTaxIdentifier()); + $vendor->setBankAccountNumber($command->getBankAccountNumber()); + $vendor->setPhoneNumber($command->getPhoneNumber()); + $vendor->setDescription($command->getDescription()); + $vendor->setVendorAddress($command->getVendorAddress()); + $vendor->setSlug($command->getSlug()); + + $this->manager->persist($vendor); + + return $vendor; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Messenger/CommandHandler/Vendor/UpdateProductListingHandler.php b/OpenMarketplace/src/Component/Core/Api/Messenger/CommandHandler/Vendor/UpdateProductListingHandler.php new file mode 100644 index 0000000..174e79c --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Messenger/CommandHandler/Vendor/UpdateProductListingHandler.php @@ -0,0 +1,55 @@ +getProductListing() + ?->getId(); + Assert::integer($productListingId); + + /** @var ListingInterface $productListing */ + $productListing = $this->productListingRepository->find($productListingId); + Assert::isInstanceOf($productListing, ListingInterface::class); + + /** @var DraftInterface $newDraft */ + $newDraft = $updateProductListing->getProductDraft(); + Assert::isInstanceOf($newDraft, DraftInterface::class); + + $newDraft->setProductListing($productListing); + + $previousDraft = $productListing->getLatestDraft(); + Assert::isInstanceOf($previousDraft, DraftInterface::class); + + $newDraft->setCode($previousDraft->getCode()); + + $this->listingPersister->updateLatestDraftWith($productListing, $newDraft); + + return $productListing; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Messenger/CommandHandler/Vendor/UploadVendorBackgroundImageHandler.php b/OpenMarketplace/src/Component/Core/Api/Messenger/CommandHandler/Vendor/UploadVendorBackgroundImageHandler.php new file mode 100644 index 0000000..bacedf6 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Messenger/CommandHandler/Vendor/UploadVendorBackgroundImageHandler.php @@ -0,0 +1,59 @@ +getFile()) { + throw new \DomainException('File should be set'); + } + + $owner = $command->getOwner(); + if (!$owner) { + throw new \DomainException('Owner should be set'); + } + + $backgroundImage = $this->vendorBackgroundImageFactory->createNew(); + $backgroundImage->setFile($command->getFile()); + $backgroundImage->setOwner($owner); + + $oldImage = $owner->getBackgroundImage(); + if (null !== $oldImage) { + $this->vendorBackgroundImageRepository->remove($oldImage); + } + $owner->setBackgroundImage($backgroundImage); + + $this->imageUploader->upload($backgroundImage); + + $this->manager->persist($owner); + $this->manager->persist($backgroundImage); + + return $backgroundImage; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Messenger/CommandHandler/Vendor/UploadVendorLogoImageHandler.php b/OpenMarketplace/src/Component/Core/Api/Messenger/CommandHandler/Vendor/UploadVendorLogoImageHandler.php new file mode 100644 index 0000000..f6cb09e --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Messenger/CommandHandler/Vendor/UploadVendorLogoImageHandler.php @@ -0,0 +1,59 @@ +getFile()) { + throw new \DomainException('File should be set'); + } + + $owner = $command->getOwner(); + if (!$owner) { + throw new \DomainException('Owner should be set'); + } + + $image = $this->vendorImageFactory->createNew(); + $image->setFile($command->getFile()); + $image->setOwner($owner); + + $oldImage = $owner->getImage(); + if (null !== $oldImage) { + $this->vendorImageRepository->remove($oldImage); + } + $owner->setImage($image); + + $this->imageUploader->upload($image); + + $this->manager->persist($owner); + $this->manager->persist($image); + + return $image; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Provider/PathPrefixProvider.php b/OpenMarketplace/src/Component/Core/Api/Provider/PathPrefixProvider.php new file mode 100644 index 0000000..c74ab63 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Provider/PathPrefixProvider.php @@ -0,0 +1,49 @@ +shopVendorApiUriBeginning)) { + return self::VENDOR_PREFIX; + } + + return $this->basePathPrefixProvider->getPathPrefix($path); + } + + public function getCurrentPrefix(): ?string + { + $section = $this->sectionProvider->getSection(); + if (null !== $this->vendorContext->getVendor() && $section instanceof ShopVendorApiSection) { + return sprintf('%s_%s', PathPrefixes::SHOP_PREFIX, self::VENDOR_PREFIX); + } + + return $this->basePathPrefixProvider->getCurrentPrefix(); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Provider/VendorProvider.php b/OpenMarketplace/src/Component/Core/Api/Provider/VendorProvider.php new file mode 100644 index 0000000..fd4ee39 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Provider/VendorProvider.php @@ -0,0 +1,35 @@ +getVendor()) { + /** @var VendorInterface $vendor */ + $vendor = $this->vendorFactory->createNew(); + $vendor->setShopUser($shopUser); + } + + return $vendor; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Provider/VendorProviderInterface.php b/OpenMarketplace/src/Component/Core/Api/Provider/VendorProviderInterface.php new file mode 100644 index 0000000..a0c05ec --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Provider/VendorProviderInterface.php @@ -0,0 +1,20 @@ + + + + + + + + + GET + /shop/account/vendor/categories + + shop:account:vendor:category:read + + + + + + GET + /shop/account/vendor/categories/{id} + + shop:account:vendor:category:read + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/Conversation.xml b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/Conversation.xml new file mode 100644 index 0000000..3efef7d --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/Conversation.xml @@ -0,0 +1,77 @@ + + + + + + + + + GET + /shop/account/vendor/conversations + + shop:account:vendor:conversation:read + + + + + POST + /shop/account/vendor/conversations + + shop:account:vendor:conversation:write + + + shop:account:vendor:conversation:write + + is_granted("VENDOR_AWARE_OBJECT_CREATE", object) + + + + + GET + /shop/account/vendor/conversations/{id} + + shop:account:vendor:conversation:read + + is_granted("UPDATE-CONVERSATION", object) + + + + PUT + /shop/account/vendor/conversations/{id} + + shop:account:vendor:conversation:write + + + shop:account:vendor:conversation:write + + is_granted("UPDATE-CONVERSATION", object) + + Add message to conversation + + + + + PATCH + /shop/account/vendor/conversations/{id}/archive + false + bitbag.open_marketplace.component.core.api.controller.vendor.accept_archive_conversation_action + + shop:account:vendor:conversation:read + + + Accepts Conversation archive request + + is_granted("UPDATE-CONVERSATION", object) + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/Customer.xml b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/Customer.xml new file mode 100644 index 0000000..559d35f --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/Customer.xml @@ -0,0 +1,113 @@ + + + + + + + + sylius + + + + POST + /shop/customers + + Registers a new customer + + + shop:customer:create + + input + Sylius\Bundle\ApiBundle\Command\Account\RegisterShopUser + false + + + + GET + /shop/account/vendor/customers + + Retrieves the collection of Customers who bought Vendor's products. + + + shop:account:vendor:customer:read + + + bitbag.open_marketplace.component.core.api.filter.search_customer + bitbag.open_marketplace.component.core.api.filter.boolean_customer + + + + + + + GET + /admin/customers/{id} + + admin:customer:read + + + + + GET + /shop/account/vendor/customers/{id} + + Retrieves a Customer who bought Vendor's products. + + + shop:account:vendor:customer:read + + + + + GET + /shop/customers/{id} + + + shop:customer:read + + + + + + PUT + /shop/customers/{id}/password + input + Sylius\Bundle\ApiBundle\Command\Account\ChangeShopUserPassword + false + + shop:customer:password:update + + + Change password for logged in customer + + + + + PUT + /shop/customers/{id} + + shop:customer:update + + + shop:customer:read + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/Order.xml b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/Order.xml new file mode 100644 index 0000000..8735276 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/Order.xml @@ -0,0 +1,461 @@ + + + + + + + sylius + + + + GET + admin/orders + + admin:order:read + + + + + POST + /shop/orders + input + Sylius\Bundle\ApiBundle\Command\Cart\PickupCart + + shop:order:read + + + shop:order:create + + + Pickups a new cart. Provided locale code has to be one of available for a particular channel. + + + + + GET + /shop/account/vendor/orders + + Retrieves the collection of orders that contain vendor's product. + + + bitbag.open_marketplace.component.core.api.filter.search_order + bitbag.open_marketplace.component.core.api.filter.date_order + + + shop:account:vendor:order:read + + + + + GET + /shop/orders + + + shop:order:read + + + + + + + + + GET + /admin/orders/{tokenValue} + + admin:order:read + + + + + GET + /shop/account/vendor/orders/{tokenValue} + + Retrieves an order that contain vendor's product. + + + shop:account:vendor:order:details + + is_granted("OWNIT", object) + + + + GET + /shop/orders/{tokenValue} + + shop:cart:read + + + + + DELETE + /shop/orders/{tokenValue} + + Deletes cart + + + shop:order:read + + + + + PATCH + /admin/orders/{tokenValue}/cancel + false + Sylius\Bundle\ApiBundle\Applicator\OrderStateMachineTransitionApplicatorInterface:cancel + + + admin:order:read + + + + admin:order:update + + + Cancels Order + + + + + PATCH + /shop/account/vendor/orders/{tokenValue}/cancel + false + Sylius\Bundle\ApiBundle\Applicator\OrderStateMachineTransitionApplicatorInterface:cancel + + is_granted("VENDOR_ORDER_CANCEL", object) and is_granted("OWNIT", object) + + + Cancels Order + You can only cancel an order if the order is paid for, but not shipped yet. + + + + admin:order:read + + + + + + POST + /shop/orders/{tokenValue}/items + input + Sylius\Bundle\ApiBundle\Command\Cart\AddItemToCart + + shop:cart:read + + + shop:cart:add_item + + + Adds Item to cart + + + + + PATCH + + sylius + + /shop/orders/{tokenValue}/shipments/{shipmentId} + input + Sylius\Bundle\ApiBundle\Command\Checkout\ChooseShippingMethod + + shop:cart:select_shipping_method + + + shop:cart:read + + + Selects shipping methods for particular shipment + + + tokenValue + path + true + + string + + + + shipmentId + path + true + + string + + + + + + + + PATCH + /shop/orders/{tokenValue}/payments/{paymentId} + input + Sylius\Bundle\ApiBundle\Command\Checkout\ChoosePaymentMethod + + shop:cart:select_payment_method + + + shop:cart:read + + + Selects payment methods for particular payment + + + tokenValue + path + true + + string + + + + paymentId + path + true + + string + + + + + + + + PATCH + /shop/account/orders/{tokenValue}/payments/{paymentId} + input + Sylius\Bundle\ApiBundle\Command\Account\ChangePaymentMethod + + shop:order:account:change_payment_method + + + shop:order:account:read + + + Change the payment method as logged shop user + + + tokenValue + path + true + + string + + + + paymentId + path + true + + string + + + + + + + + GET + Sylius\Bundle\ApiBundle\Controller\Payment\GetPaymentConfiguration + /shop/orders/{tokenValue}/payments/{paymentId}/configuration + + Retrieve payment method configuration + + + tokenValue + path + true + + string + + + + paymentId + path + true + + string + + + + + + + + PATCH + /shop/orders/{tokenValue}/complete + + sylius + sylius_checkout_complete + + input + Sylius\Bundle\ApiBundle\Command\Checkout\CompleteOrder + + shop:cart:complete + + + shop:cart:read + + + Completes checkout + + + + + DELETE + /shop/orders/{tokenValue}/items/{itemId} + input + Sylius\Bundle\ApiBundle\Controller\DeleteOrderItemAction + false + + shop:cart:remove_item + + + + + tokenValue + path + true + + string + + + + itemId + path + true + + string + + + + + + + + PATCH + /shop/orders/{tokenValue}/items/{orderItemId} + input + Sylius\Bundle\ApiBundle\Command\Cart\ChangeItemQuantityInCart + + shop:cart:read + + + shop:cart:change_quantity + + + Changes quantity of order item + + + tokenValue + path + true + + string + + + + orderItemId + path + true + + string + + + + + + + + PUT + /shop/orders/{tokenValue} + input + Sylius\Bundle\ApiBundle\Command\Checkout\UpdateCart + + shop:cart:update + + + shop:cart:read + + + Addresses cart to given location, logged in Customer does not have to provide an email. Applies coupon to cart. + + + + + + + GET + /shop/orders/{tokenValue}/items + + + + GET + /admin/orders/{tokenValue}/shipments + + + + GET + /admin/orders/{tokenValue}/payments + + + + GET + /shop/orders/{tokenValue}/adjustments + + + + GET + /shop/orders/{tokenValue}/payments/{payments}/methods + + + + GET + /shop/orders/{tokenValue}/shipments/{shipments}/methods + + + + GET + /shop/orders/{tokenValue}/items/{items}/adjustments + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductListing/Draft.xml b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductListing/Draft.xml new file mode 100644 index 0000000..e1b8f6d --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductListing/Draft.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + GET + /shop/account/vendor/product-drafts/{uuid} + + shop:account:vendor:product_draft:read + + is_granted("OWNIT", object) + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductListing/DraftAttribute.xml b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductListing/DraftAttribute.xml new file mode 100644 index 0000000..6ed9521 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductListing/DraftAttribute.xml @@ -0,0 +1,74 @@ + + + + + + + + + + POST + + ApiDraftAttribute + + /shop/account/vendor/product-draft/attributes + + shop:account:vendor:draft_attribute:create + + + shop:account:vendor:draft_attribute:read + + is_granted("VENDOR_AWARE_OBJECT_CREATE", object) + + + GET + /shop/account/vendor/product-draft/attributes + + shop:account:vendor:draft_attribute:read + + + + + + + GET + /shop/account/vendor/product-draft/attributes/{uuid} + + shop:account:vendor:draft_attribute:read + + is_granted("OWNIT", object) + + + + PUT + + ApiDraftAttribute + + /shop/account/vendor/product-draft/attributes/{uuid} + + shop:account:vendor:draft_attribute:update + + + shop:account:vendor:draft_attribute:read + + is_granted("OWNIT", object) + + + + DELETE + /shop/account/vendor/product-draft/attributes/{uuid} + is_granted("OWNIT", object) + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductListing/DraftAttributeTranslation.xml b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductListing/DraftAttributeTranslation.xml new file mode 100644 index 0000000..a4ca670 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductListing/DraftAttributeTranslation.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + GET + /shop/account/vendor/product-draft/attribute-translations/{uuid} + + shop:account:vendor:draft_attribute_translation:read + + is_granted("TRANSLATABLE_VENDOR_AWARE_OBJECT_READ", object) + + + + PUT + + ApiDraftAttribute + + /shop/account/vendor/product-draft/attribute-translations/{uuid} + + shop:account:vendor:draft_attribute_translation:update + + + shop:account:vendor:draft_attribute_translation:read + + is_granted("TRANSLATABLE_VENDOR_AWARE_OBJECT_UPDATE", object) + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductListing/DraftTranslation.xml b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductListing/DraftTranslation.xml new file mode 100644 index 0000000..9caaf97 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductListing/DraftTranslation.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + GET + /shop/account/vendor/product-draft/translations/{uuid} + + shop:draft_product_translation:read + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductListing/Listing.xml b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductListing/Listing.xml new file mode 100644 index 0000000..d233c71 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductListing/Listing.xml @@ -0,0 +1,126 @@ + + + + + + + + + POST + + ApiProductListing + + /shop/account/vendor/product-listings + + +Body parameters: +- `attributes.attribute` accept id of DraftAttributes e.g. `/api/v2/shop/account/vendor/product-draft/attributes/4DGR-334Spds`. +- `mainTaxon`, `productDraftTaxons.taxon` accept id of Taxon e.g. `/api/v2/shop/taxons/clothes`. +- `images` as an array of files + + + + shop:account:vendor:product_listing:create + + + shop:account:vendor:product_listing:read + + is_granted("VENDOR_AWARE_OBJECT_CREATE", object) + input + BitBag\OpenMarketplace\Component\Core\Api\Messenger\Command\Vendor\CreateProductListing + 201 + + + + GET + /shop/account/vendor/product-listings + + shop:account:vendor:product_listing:read + + + bitbag.open_marketplace.component.core.api.filter.search_product_listing + + + + + + + GET + /shop/account/vendor/product-listings/{uuid} + + shop:account:vendor:product_listing:read + + is_granted("OWNIT", object) + + + + PUT + + ApiProductListing + + /shop/account/vendor/product-listings/{uuid} + + +Body parameters: +- `attributes.attribute` accept id of DraftAttributes e.g. `/api/v2/shop/account/vendor/product-draft/attributes/4DGR-334Spds`. +- `mainTaxon`, `productDraftTaxons.taxon` accept id of Taxon e.g. `/api/v2/shop/taxons/clothes`. +- `images` as an array of files + + + + shop:account:vendor:product_listing:update + + + shop:account:vendor:product_listing:read + + is_granted("OWNIT", object) + input + BitBag\OpenMarketplace\Component\Core\Api\Messenger\Command\Vendor\UpdateProductListing + + + + PUT + /shop/account/vendor/product-listings/{uuid}/send-to-verification + + Send to verification by administrator the product. + + false + is_granted("OWNIT", object) + bitbag.open_marketplace.component.core.api.controller.vendor.send_product_listing_to_verification_action + + shop:account:vendor:product_listing:read + + + + + DELETE + /shop/account/vendor/product-listings/{uuid} + bitbag.open_marketplace.component.core.api.controller.vendor.delete_product_listing_action + is_granted("OWNIT", object) + + + + + + GET + /shop/account/vendor/product-listings/{uuid}/product-drafts + + shop:account:vendor:product_listing:drafts:read + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductVariant.xml b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductVariant.xml new file mode 100644 index 0000000..31ecd11 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/ProductVariant.xml @@ -0,0 +1,135 @@ + + + + + + + sylius + + + + GET + /admin/product-variants/{code} + + admin:product_variant:read + + + + + PUT + /admin/product-variants/{code} + + admin:product_variant:read + + + admin:product_variant:update + + + + + GET + /shop/product-variants/{code} + + shop:product_variant:read + + + + + GET + /shop/account/vendor/product-variants/{code}/inventory + + Retrieves an inventory of Vendor's product variant. + + + shop:account:vendor:product-variants:inventory:read + + is_granted("OWNS_VARIANT", object) + + + + PUT + /shop/account/vendor/product-variants/{code}/inventory + + Replaces the inventory of Vendor's product variant. + + + shop:account:vendor:product-variants:inventory:update + + + shop:account:vendor:product-variants:inventory:read + + is_granted("OWNS_VARIANT", object) + + + + + + GET + /admin/product-variants + + admin:product_variant:read + + + + + POST + /admin/product-variants + + admin:product_variant:create + + + admin:product_variant:create + + + + + GET + /shop/product-variants + + sylius.api.product_variant_product_filter + Sylius\Bundle\ApiBundle\Filter\Doctrine\ProductVariantOptionValueFilter + + + shop:product_variant:read + + + + + GET + /shop/account/vendor/product-variants/inventory + + Retrieves the collection of inventory Vendor's product variants. + + + shop:account:vendor:product-variants:inventory:read + + + + + + + + + + + array + + + string + string + string + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/Vendor.xml b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/Vendor.xml new file mode 100644 index 0000000..fa78768 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/Vendor.xml @@ -0,0 +1,117 @@ + + + + + + + + + + POST + + Default + VendorUserRegister + + /shop/account/vendor/register + + Registers as a new vendor + Body parameter `country` accept id of Country e.g. `/api/v2/shop/countries/EU`. + + + shop:account:vendor:create + + + shop:account:vendor:read + + input + BitBag\OpenMarketplace\Component\Core\Api\Messenger\Command\Vendor\RegisterVendor + 201 + + + + GET + /admin/vendors + + admin:vendor:read + + + + + GET + /shop/vendors + + shop:vendor:read + + + + + + + GET + /shop/vendors/{uuid} + + shop:vendor:read + + + + + GET + /shop/account/vendors/{uuid} + + shop:account:vendor:read + + + + + GET + /admin/vendors/{uuid} + + admin:vendor:read + + + + + PUT + + Default + VendorUser + + /shop/account/vendors/{uuid} + + Body parameter `country` accept id of Country e.g. `/api/v2/shop/countries/EU`. + + + shop:account:vendor:update + + + shop:account:vendor:read + + + + + PUT + + Default + VendorUser + + /admin/vendors/{uuid} + + admin:vendor:update + + + admin:vendor:read + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/VendorBackgroundImage.xml b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/VendorBackgroundImage.xml new file mode 100644 index 0000000..9c3611a --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/VendorBackgroundImage.xml @@ -0,0 +1,72 @@ + + + + + + + + + + POST + + ApiUploadVendorBackgroundImage + + /shop/account/vendor/background-image + + + + + + object + + + string + binary + + + + + + + + + shop:account:vendor:background_image:create + + + shop:account:vendor:background_image:read + + input + BitBag\OpenMarketplace\Component\Core\Api\Messenger\Command\Vendor\UploadVendorBackgroundImage + 201 + + + + + + GET + /shop/account/vendor/background-image/{uuid} + + shop:account:vendor:vendor_background_image:read + + + + + is_granted("VENDOR_BACKGROUND_IMAGE_DELETE", object) + DELETE + /shop/account/vendor/background-image/{uuid} + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/VendorLogoImage.xml b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/VendorLogoImage.xml new file mode 100644 index 0000000..00c2f95 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/api_resources/VendorLogoImage.xml @@ -0,0 +1,72 @@ + + + + + + + + + + POST + + ApiUploadVendorImage + + /shop/account/vendor/logo + + + + + + object + + + string + binary + + + + + + + + + shop:account:vendor:logo:create + + + shop:account:vendor:logo:read + + input + BitBag\OpenMarketplace\Component\Core\Api\Messenger\Command\Vendor\UploadVendorImage + 201 + + + + + + GET + /shop/account/vendor/logo/{uuid} + + shop:account:vendor:logo:read + + + + + is_granted("VENDOR_IMAGE_DELETE", object) + DELETE + /shop/account/vendor/logo/{uuid} + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Address.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Address.xml new file mode 100644 index 0000000..76abcdd --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Address.xml @@ -0,0 +1,61 @@ + + + + + + + + shop:account:vendor:order:details + + + shop:account:vendor:order:details + + + shop:account:vendor:order:details + shop:account:vendor:customer:read + + + shop:account:vendor:order:details + shop:account:vendor:customer:read + + + shop:account:vendor:order:details + shop:account:vendor:customer:read + + + shop:account:vendor:order:details + shop:account:vendor:customer:read + + + shop:account:vendor:order:details + shop:account:vendor:customer:read + + + shop:account:vendor:order:details + shop:account:vendor:customer:read + + + shop:account:vendor:order:details + shop:account:vendor:customer:read + + + shop:account:vendor:order:details + shop:account:vendor:customer:read + + + shop:account:vendor:order:details + shop:account:vendor:customer:read + + + shop:account:vendor:order:details + shop:account:vendor:customer:read + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Commands/Vendor/CreateProductListing.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Commands/Vendor/CreateProductListing.xml new file mode 100644 index 0000000..4b1b500 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Commands/Vendor/CreateProductListing.xml @@ -0,0 +1,18 @@ + + + + + + + + shop:account:vendor:product_listing:create + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Commands/Vendor/RegisterVendor.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Commands/Vendor/RegisterVendor.xml new file mode 100644 index 0000000..fe43dc2 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Commands/Vendor/RegisterVendor.xml @@ -0,0 +1,33 @@ + + + + + + + + shop:account:vendor:create + + + shop:account:vendor:create + + + shop:account:vendor:create + + + shop:account:vendor:create + + + shop:account:vendor:create + + + shop:account:vendor:create + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Commands/Vendor/UpdateProductListing.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Commands/Vendor/UpdateProductListing.xml new file mode 100644 index 0000000..7a95f09 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Commands/Vendor/UpdateProductListing.xml @@ -0,0 +1,18 @@ + + + + + + + + shop:account:vendor:product_listing:update + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Commands/Vendor/UploadVendorBackgroundImage.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Commands/Vendor/UploadVendorBackgroundImage.xml new file mode 100644 index 0000000..5a10a84 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Commands/Vendor/UploadVendorBackgroundImage.xml @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Commands/Vendor/UploadVendorImage.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Commands/Vendor/UploadVendorImage.xml new file mode 100644 index 0000000..b148eff --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Commands/Vendor/UploadVendorImage.xml @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Customer.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Customer.xml new file mode 100644 index 0000000..8d23237 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Customer.xml @@ -0,0 +1,50 @@ + + + + + + + + shop:account:vendor:order:read + shop:account:vendor:customer:read + + + + shop:account:vendor:order:read + shop:account:vendor:customer:read + + + + shop:account:vendor:order:read + shop:account:vendor:customer:read + + + + shop:account:vendor:order:read + shop:account:vendor:customer:read + + + + shop:account:vendor:customer:read + + + + shop:account:vendor:order:read + + + + shop:account:vendor:customer:read + + + + shop:account:vendor:customer:read + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Messaging/Category.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Messaging/Category.xml new file mode 100644 index 0000000..a1775bb --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Messaging/Category.xml @@ -0,0 +1,19 @@ + + + + + + + + shop:account:vendor:conversation:read + shop:account:vendor:category:read + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Messaging/Conversation.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Messaging/Conversation.xml new file mode 100644 index 0000000..2dad72e --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Messaging/Conversation.xml @@ -0,0 +1,29 @@ + + + + + + + + shop:account:vendor:conversation:read + + + shop:account:vendor:conversation:write + shop:account:vendor:conversation:read + + + shop:account:vendor:conversation:write + shop:account:vendor:conversation:read + + + shop:account:vendor:conversation:read + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Messaging/Message.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Messaging/Message.xml new file mode 100644 index 0000000..59befc9 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Messaging/Message.xml @@ -0,0 +1,31 @@ + + + + + + + + shop:account:vendor:conversation:write + shop:account:vendor:conversation:read + + + shop:account:vendor:conversation:read + + + shop:account:vendor:conversation:read + + + shop:account:vendor:conversation:read + + + shop:account:vendor:conversation:read + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Order.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Order.xml new file mode 100644 index 0000000..f1c4afe --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Order.xml @@ -0,0 +1,115 @@ + + + + + + + + shop:account:vendor:order:read + shop:account:vendor:order:details + + + + shop:account:vendor:order:read + shop:account:vendor:order:details + + + + shop:account:vendor:order:read + shop:account:vendor:order:details + + + + shop:account:vendor:order:read + shop:account:vendor:order:details + + + + shop:account:vendor:order:read + shop:account:vendor:order:details + + + + shop:account:vendor:order:read + shop:account:vendor:order:details + + + + shop:account:vendor:order:read + shop:account:vendor:order:details + + + + shop:account:vendor:order:read + shop:account:vendor:order:details + + + + shop:account:vendor:order:read + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/OrderItem.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/OrderItem.xml new file mode 100644 index 0000000..db1a6f7 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/OrderItem.xml @@ -0,0 +1,78 @@ + + + + + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/OrderItemUnit.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/OrderItemUnit.xml new file mode 100644 index 0000000..77132e2 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/OrderItemUnit.xml @@ -0,0 +1,30 @@ + + + + + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + + shop:account:vendor:order:details + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Product.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Product.xml new file mode 100644 index 0000000..a35afa3 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Product.xml @@ -0,0 +1,51 @@ + + + + + + + + shop_account:product_listing:read + + + shop_account:product_listing:read + + + shop_account:product_listing:read + + + shop_account:product_listing:read + + + shop_account:product_listing:read + + + shop_account:product_listing:read + + + shop_account:product_listing:read + + + shop_account:product_listing:read + + + shop_account:product_listing:read + + + shop_account:product_listing:read + + + shop_account:product_listing:read + + + shop_account:product_listing:read + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/Draft.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/Draft.xml new file mode 100644 index 0000000..14fb785 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/Draft.xml @@ -0,0 +1,76 @@ + + + + + + + + shop:account:vendor:product_draft:read + shop:account:vendor:product_listing:read + + + shop:account:vendor:product_draft:read + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + + + shop:account:vendor:product_draft:read + shop:account:vendor:product_listing:read + + + shop:account:vendor:product_draft:read + shop:account:vendor:product_listing:read + + + shop:account:vendor:product_draft:read + shop:account:vendor:product_listing:read + + + shop:account:vendor:product_draft:read + shop:account:vendor:product_listing:read + + + shop:account:vendor:product_draft:read + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:product_draft:read + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:product_draft:read + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:product_draft:read + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:product_draft:read + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:product_draft:read + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftAttribute.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftAttribute.xml new file mode 100644 index 0000000..11a86c5 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftAttribute.xml @@ -0,0 +1,48 @@ + + + + + + + + shop:account:vendor:draft_attribute:read + + + shop:account:vendor:draft_attribute:read + + + shop:account:vendor:draft_attribute:create + shop:account:vendor:draft_attribute:read + + + shop:account:vendor:draft_attribute:create + shop:account:vendor:draft_attribute:read + + + shop:account:vendor:draft_attribute:create + shop:account:vendor:draft_attribute:read + + + shop:account:vendor:draft_attribute:create + shop:account:vendor:draft_attribute:read + shop:account:vendor:draft_attribute:update + + + shop:account:vendor:draft_attribute:create + shop:account:vendor:draft_attribute:read + shop:account:vendor:draft_attribute:update + + + shop:account:vendor:draft_attribute:create + shop:account:vendor:draft_attribute:read + shop:account:vendor:draft_attribute:update + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftAttributeTranslation.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftAttributeTranslation.xml new file mode 100644 index 0000000..5c736f1 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftAttributeTranslation.xml @@ -0,0 +1,31 @@ + + + + + + + + shop:account:vendor:draft_attribute_translation:read + shop:account:vendor:draft_attribute:read + + + shop:account:vendor:draft_attribute_translation:read + shop:account:vendor:draft_attribute_translation:update + shop:account:vendor:draft_attribute:create + shop:account:vendor:draft_attribute:read + + + shop:account:vendor:draft_attribute_translation:read + shop:account:vendor:draft_attribute_translation:update + shop:account:vendor:draft_attribute:create + shop:account:vendor:draft_attribute:read + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftAttributeValue.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftAttributeValue.xml new file mode 100644 index 0000000..d3c7d47 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftAttributeValue.xml @@ -0,0 +1,29 @@ + + + + + + + + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftImage.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftImage.xml new file mode 100644 index 0000000..a03eacb --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftImage.xml @@ -0,0 +1,24 @@ + + + + + + + + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftTaxon.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftTaxon.xml new file mode 100644 index 0000000..9454e70 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftTaxon.xml @@ -0,0 +1,28 @@ + + + + + + + + shop:account:vendor:product_listing:read + + + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftTranslation.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftTranslation.xml new file mode 100644 index 0000000..de7c5ef --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/DraftTranslation.xml @@ -0,0 +1,61 @@ + + + + + + + + shop:account:vendor:draft_product_translation:read + shop:account:vendor:product_listing:read + + + shop:account:vendor:draft_product_translation:read + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:draft_product_translation:read + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:draft_product_translation:read + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:draft_product_translation:read + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:draft_product_translation:read + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:draft_product_translation:read + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:draft_product_translation:read + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/Listing.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/Listing.xml new file mode 100644 index 0000000..dc4cd05 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/Listing.xml @@ -0,0 +1,39 @@ + + + + + + + + shop:account:vendor:product_listing:read + + + shop:account:vendor:product_listing:read + + + shop:account:vendor:product_listing:read + + + shop:account:vendor:product_listing:read + + + shop:account:vendor:product_listing:read + + + shop:account:vendor:product_listing:read + + + shop:account:vendor:product_listing:drafts:read + + + shop:account:vendor:product_listing:read + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/ListingPrice.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/ListingPrice.xml new file mode 100644 index 0000000..ce6d884 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductListing/ListingPrice.xml @@ -0,0 +1,39 @@ + + + + + + + + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + shop:account:vendor:product_listing:create + shop:account:vendor:product_listing:read + shop:account:vendor:product_listing:update + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductVariant.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductVariant.xml new file mode 100644 index 0000000..658dec7 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ProductVariant.xml @@ -0,0 +1,33 @@ + + + + + + + + shop:account:vendor:product-variants:inventory:read + shop:account:vendor:order:details + + + shop:account:vendor:product-variants:inventory:read + + + shop:account:vendor:product-variants:inventory:read + shop:account:vendor:product-variants:inventory:update + + + shop:account:vendor:product-variants:inventory:read + shop:account:vendor:product-variants:inventory:update + + + shop:account:vendor:product-variants:inventory:read + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Shipment.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Shipment.xml new file mode 100644 index 0000000..b892cbb --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Shipment.xml @@ -0,0 +1,26 @@ + + + + + + + + admin:order:read + admin:shipment:read + shop:cart:read + shop:order:account:read + shop:shipment:read + + + + shop:account:vendor:order:read + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ShipmentMethod.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ShipmentMethod.xml new file mode 100644 index 0000000..6e88d50 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ShipmentMethod.xml @@ -0,0 +1,23 @@ + + + + + + + + shop:account:vendor:order:read + + + + shop:account:vendor:order:read + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ShopUser.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ShopUser.xml new file mode 100644 index 0000000..6f4f5fa --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/ShopUser.xml @@ -0,0 +1,27 @@ + + + + + + + + shop:customer:read + shop:account:vendor:customer:read + + + + shop:account:vendor:customer:read + + + + shop:account:vendor:customer:read + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Vendor.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Vendor.xml new file mode 100644 index 0000000..a30a749 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/Vendor.xml @@ -0,0 +1,98 @@ + + + + + + + + admin:vendor:read + + + admin:vendor:read + admin:order:read + admin:shipment:read + shop:cart:read + shop:order:account:read + shop:shipment:read + shop:customer:read + shop:vendor:read + shop:account:vendor:read + shop:account:vendor:create + shop:account:vendor:vendor_image:read + + + admin:vendor:read + admin:order:read + admin:shipment:read + shop:cart:read + shop:order:account:read + shop:shipment:read + shop:customer:read + shop:vendor:read + shop:account:vendor:read + shop:account:vendor:create + + + admin:vendor:update + admin:vendor:read + shop:vendor:read + shop:account:vendor:read + shop:account:vendor:update + + + admin:vendor:update + admin:vendor:read + shop:account:vendor:read + shop:account:vendor:update + + + admin:vendor:update + admin:vendor:read + shop:account:vendor:read + shop:account:vendor:update + + + admin:vendor:update + admin:vendor:read + shop:account:vendor:read + shop:account:vendor:update + + + admin:vendor:update + admin:vendor:read + shop:account:vendor:read + shop:account:vendor:update + + + admin:vendor:update + admin:vendor:read + + + admin:vendor:update + admin:vendor:read + shop:account:vendor:read + shop:account:vendor:update + + + admin:vendor:update + admin:vendor:read + shop:vendor:read + shop:account:vendor:read + + + shop:vendor:read + shop:account:vendor:read + + + admin:vendor:update + admin:vendor:read + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/VendorAddress.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/VendorAddress.xml new file mode 100644 index 0000000..2c0165d --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/VendorAddress.xml @@ -0,0 +1,43 @@ + + + + + + + + admin:vendor:read + admin:vendor:update + shop:account:vendor:create + shop:account:vendor:read + shop:account:vendor:update + + + admin:vendor:read + admin:vendor:update + shop:account:vendor:create + shop:account:vendor:read + shop:account:vendor:update + + + admin:vendor:read + admin:vendor:update + shop:account:vendor:create + shop:account:vendor:read + shop:account:vendor:update + + + admin:vendor:read + admin:vendor:update + shop:account:vendor:create + shop:account:vendor:read + shop:account:vendor:update + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/VendorBackgroundImage.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/VendorBackgroundImage.xml new file mode 100644 index 0000000..3543c8b --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/VendorBackgroundImage.xml @@ -0,0 +1,28 @@ + + + + + + + + shop:vendor:read + shop:account:vendor:read + shop:account:vendor:background_image:read + + + shop:vendor:read + shop:account:vendor:read + shop:account:vendor:background_image:read + + + shop:account:vendor:background_image:read + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/serialization/VendorImage.xml b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/VendorImage.xml new file mode 100644 index 0000000..7f6b568 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/serialization/VendorImage.xml @@ -0,0 +1,31 @@ + + + + + + + + shop:vendor:read + shop:account:vendor:read + shop:account:vendor:logo:read + shop:account:vendor:logo:create + + + shop:vendor:read + shop:account:vendor:read + shop:account:vendor:logo:read + shop:account:vendor:logo:create + + + shop:account:vendor:logo:read + shop:account:vendor:logo:create + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/services.xml b/OpenMarketplace/src/Component/Core/Api/Resources/services.xml new file mode 100644 index 0000000..368cb54 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/services.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/services/command_handlers.xml b/OpenMarketplace/src/Component/Core/Api/Resources/services/command_handlers.xml new file mode 100644 index 0000000..8317138 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/services/command_handlers.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/services/controllers.xml b/OpenMarketplace/src/Component/Core/Api/Resources/services/controllers.xml new file mode 100644 index 0000000..7d341d8 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/services/controllers.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/services/data_persisters.xml b/OpenMarketplace/src/Component/Core/Api/Resources/services/data_persisters.xml new file mode 100644 index 0000000..6e5cd37 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/services/data_persisters.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/services/data_providers.xml b/OpenMarketplace/src/Component/Core/Api/Resources/services/data_providers.xml new file mode 100644 index 0000000..cb8f6ca --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/services/data_providers.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/services/data_transformers.xml b/OpenMarketplace/src/Component/Core/Api/Resources/services/data_transformers.xml new file mode 100644 index 0000000..0e4e03f --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/services/data_transformers.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/services/doctrine_extensions.xml b/OpenMarketplace/src/Component/Core/Api/Resources/services/doctrine_extensions.xml new file mode 100644 index 0000000..96f38a1 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/services/doctrine_extensions.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/services/event_subscribers.xml b/OpenMarketplace/src/Component/Core/Api/Resources/services/event_subscribers.xml new file mode 100644 index 0000000..182fc4a --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/services/event_subscribers.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/services/factories.xml b/OpenMarketplace/src/Component/Core/Api/Resources/services/factories.xml new file mode 100644 index 0000000..8264ec3 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/services/factories.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/services/filters.xml b/OpenMarketplace/src/Component/Core/Api/Resources/services/filters.xml new file mode 100644 index 0000000..2d1badd --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/services/filters.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + partial + exact + exact + exact + exact + partial + + + + + + + + + + + + + + partial + exact + + + + + + + partial + partial + partial + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/services/generators.xml b/OpenMarketplace/src/Component/Core/Api/Resources/services/generators.xml new file mode 100644 index 0000000..d30134f --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/services/generators.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/services/providers.xml b/OpenMarketplace/src/Component/Core/Api/Resources/services/providers.xml new file mode 100644 index 0000000..fd6e838 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/services/providers.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + %sylius.security.new_api_user_account_vendor_route% + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/services/resolvers.xml b/OpenMarketplace/src/Component/Core/Api/Resources/services/resolvers.xml new file mode 100644 index 0000000..bb4b0e6 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/services/resolvers.xml @@ -0,0 +1,23 @@ + + + + + + + + + + %sylius.security.new_api_user_account_vendor_route% + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/services/serializers.xml b/OpenMarketplace/src/Component/Core/Api/Resources/services/serializers.xml new file mode 100644 index 0000000..0dbc03c --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/services/serializers.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/services/validators.xml b/OpenMarketplace/src/Component/Core/Api/Resources/services/validators.xml new file mode 100644 index 0000000..2a8a422 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/services/validators.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/services/voters.xml b/OpenMarketplace/src/Component/Core/Api/Resources/services/voters.xml new file mode 100644 index 0000000..7e826be --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/services/voters.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/validation/Messenger/Command/CreateProductListing.xml b/OpenMarketplace/src/Component/Core/Api/Resources/validation/Messenger/Command/CreateProductListing.xml new file mode 100644 index 0000000..b81fe74 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/validation/Messenger/Command/CreateProductListing.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/validation/Messenger/Command/Vendor/RegisterVendor.xml b/OpenMarketplace/src/Component/Core/Api/Resources/validation/Messenger/Command/Vendor/RegisterVendor.xml new file mode 100644 index 0000000..0d37aa6 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/validation/Messenger/Command/Vendor/RegisterVendor.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/validation/Messenger/Command/Vendor/UpdateProductListing.xml b/OpenMarketplace/src/Component/Core/Api/Resources/validation/Messenger/Command/Vendor/UpdateProductListing.xml new file mode 100644 index 0000000..ad315f3 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/validation/Messenger/Command/Vendor/UpdateProductListing.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/validation/Messenger/Command/Vendor/UploadVendorBackgroundImage.xml b/OpenMarketplace/src/Component/Core/Api/Resources/validation/Messenger/Command/Vendor/UploadVendorBackgroundImage.xml new file mode 100644 index 0000000..7a177ad --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/validation/Messenger/Command/Vendor/UploadVendorBackgroundImage.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/Resources/validation/Messenger/Command/Vendor/UploadVendorImage.xml b/OpenMarketplace/src/Component/Core/Api/Resources/validation/Messenger/Command/Vendor/UploadVendorImage.xml new file mode 100644 index 0000000..b2e49ff --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Resources/validation/Messenger/Command/Vendor/UploadVendorImage.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Api/SectionResolver/ShopVendorApiSection.php b/OpenMarketplace/src/Component/Core/Api/SectionResolver/ShopVendorApiSection.php new file mode 100644 index 0000000..6de9345 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/SectionResolver/ShopVendorApiSection.php @@ -0,0 +1,17 @@ +shopVendorApiUriBeginning)) { + throw new SectionCannotBeResolvedException(); + } + + return $this->shopVendorApiSectionFactory->createNew(); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Security/Voter/TranslatableVendorAwareVoter.php b/OpenMarketplace/src/Component/Core/Api/Security/Voter/TranslatableVendorAwareVoter.php new file mode 100644 index 0000000..dd5ec92 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Security/Voter/TranslatableVendorAwareVoter.php @@ -0,0 +1,76 @@ +supportedAttributes)) { + return false; + } + + if (!$subject instanceof TranslationInterface) { + return false; + } + + return $subject->getTranslatable() instanceof VendorAwareInterface; + } + + /** + * @param TranslationInterface $subject + */ + protected function voteOnAttribute( + string $attribute, + $subject, + TokenInterface $token + ): bool { + if (!in_array($attribute, $this->supportedAttributes)) { + return true; + } + + $translatable = $subject->getTranslatable(); + if (!$translatable instanceof VendorAwareInterface) { + return true; + } + + $vendor = $this->vendorContext->getVendor(); + if (null === $vendor) { + return false; + } + + /** @var VendorInterface $translatableOwner */ + $translatableOwner = $translatable->getVendor(); + + return $translatableOwner->getId() === $vendor->getId(); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Security/Voter/VendorAwareVoter.php b/OpenMarketplace/src/Component/Core/Api/Security/Voter/VendorAwareVoter.php new file mode 100644 index 0000000..5a3ec40 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Security/Voter/VendorAwareVoter.php @@ -0,0 +1,60 @@ +supportedAttributes); + + $supportsSubject = ($subject instanceof VendorAwareInterface) || ($subject instanceof ConversationInterface); + + return $supportsAttribute && $supportsSubject; + } + + /** + * @param VendorAwareInterface $subject + */ + protected function voteOnAttribute( + string $attribute, + $subject, + TokenInterface $token + ): bool { + if ( + in_array($attribute, $this->supportedAttributes) && + null === $this->vendorContext->getVendor() + ) { + return false; + } + + return true; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Security/Voter/VendorBackgroundImageVoter.php b/OpenMarketplace/src/Component/Core/Api/Security/Voter/VendorBackgroundImageVoter.php new file mode 100644 index 0000000..56ee168 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Security/Voter/VendorBackgroundImageVoter.php @@ -0,0 +1,84 @@ +voteOnDelete($attribute, $subject); + } + + return true; + } + + private function voteOnDelete(string $attribute, BackgroundImageInterface $subject): bool + { + $currentVendor = $this->getCurrentVendor(); + /** @var ?VendorInterface $subjectOwner */ + $subjectOwner = $subject->getOwner(); + + if (null === $currentVendor || null === $subjectOwner) { + return false; + } + + if ($currentVendor->getId() !== $subjectOwner->getId()) { + return false; + } + + return true; + } + + private function getCurrentVendor(): ?VendorInterface + { + $shopUser = $this->userContext->getUser(); + if (!$shopUser instanceof ShopUserInterface) { + return null; + } + + return $shopUser->getVendor(); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Security/Voter/VendorLogoImageVoter.php b/OpenMarketplace/src/Component/Core/Api/Security/Voter/VendorLogoImageVoter.php new file mode 100644 index 0000000..a0c5fd8 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Security/Voter/VendorLogoImageVoter.php @@ -0,0 +1,84 @@ +voteOnDelete($attribute, $subject); + } + + return true; + } + + private function voteOnDelete(string $attribute, LogoImageInterface $subject): bool + { + $currentVendor = $this->getCurrentVendor(); + /** @var ?VendorInterface $subjectOwner */ + $subjectOwner = $subject->getOwner(); + + if (null === $currentVendor || null === $subjectOwner) { + return false; + } + + if ($currentVendor->getId() !== $subjectOwner->getId()) { + return false; + } + + return true; + } + + private function getCurrentVendor(): ?VendorInterface + { + $shopUser = $this->userContext->getUser(); + if (!$shopUser instanceof ShopUserInterface) { + return null; + } + + return $shopUser->getVendor(); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Security/Voter/VendorOwnsVariantVoter.php b/OpenMarketplace/src/Component/Core/Api/Security/Voter/VendorOwnsVariantVoter.php new file mode 100644 index 0000000..8298a2b --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Security/Voter/VendorOwnsVariantVoter.php @@ -0,0 +1,66 @@ +getUser(); + if (!$user instanceof ShopUserInterface || null == $subject) { + return false; + } + + switch ($attribute) { + case self::OWNS_VARIANT: + return $this->doesUserOwnTheData($subject, $user); + default: + return false; + } + } + + private function doesUserOwnTheData(object $data, ShopUserInterface $user): bool + { + $loggedInVendor = $user->getVendor(); + /** @phpstan-ignore-next-line */ + $vendorData = $data->getProduct()->getVendor(); + if ($loggedInVendor === $vendorData) { + return true; + } + + return false; + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/Serializer/ProductVariantNormalizer.php b/OpenMarketplace/src/Component/Core/Api/Serializer/ProductVariantNormalizer.php new file mode 100644 index 0000000..2a420c3 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/Serializer/ProductVariantNormalizer.php @@ -0,0 +1,53 @@ +productVariantNormalizer->supportsNormalization($data, $format, $context) && $this->isNotShopVendorApiSection(); + } + + public function normalize( + $object, + string $format = null, + array $context = [] + ) { + return $this->productVariantNormalizer->normalize($object, $format, $context); + } + + private function isNotShopVendorApiSection(): bool + { + return !$this->sectionProvider->getSection() instanceof ShopVendorApiSection; + } + + public function setNormalizer(NormalizerInterface $normalizer): void + { + /** @phpstan-ignore-next-line BaseProductVariantNormalize doesn't have interface */ + $this->productVariantNormalizer->setNormalizer($normalizer); + } +} diff --git a/OpenMarketplace/src/Component/Core/Api/UuidAwareInterface.php b/OpenMarketplace/src/Component/Core/Api/UuidAwareInterface.php new file mode 100644 index 0000000..6438d9c --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Api/UuidAwareInterface.php @@ -0,0 +1,21 @@ +userContext->getUser(); + Assert::isInstanceOf($user, ShopUserInterface::class); + + if (null !== $user->getVendor()) { + $this->context->addViolation( + $constraint->message + ); + } + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Controller/Messaging/CreateMessageAction.php b/OpenMarketplace/src/Component/Core/Common/Controller/Messaging/CreateMessageAction.php new file mode 100755 index 0000000..e8d1925 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Controller/Messaging/CreateMessageAction.php @@ -0,0 +1,62 @@ +formFactory->create(MessageType::class); + $redirect = $request->attributes->get('_sylius')['redirect']; + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + /** @var Message $message */ + $message = $form->getData(); + $file = $form->get('file')->getData(); + + $this->messagePersister + ->createWithConversation($id, $message, $file); + } else { + /** @var Session $session */ + $session = $request->getSession(); + $flashBag = $session->getFlashBag(); + /** @var FormError $error */ + foreach ($form->getErrors(true) as $error) { + $flashBag->add('error', $error->getMessage()); + } + } + + return new RedirectResponse($this->urlGenerator->generate($redirect, [ + 'id' => $id, + ])); + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Controller/Messaging/CreateThreadAction.php b/OpenMarketplace/src/Component/Core/Common/Controller/Messaging/CreateThreadAction.php new file mode 100755 index 0000000..2ac9781 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Controller/Messaging/CreateThreadAction.php @@ -0,0 +1,85 @@ +attributes->get('_sylius')['template']; + + $form = $this->formFactory->create(ConversationType::class); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $redirect = $request->attributes->get('_sylius')['redirect']; + + /** @var ConversationInterface $conversation */ + $conversation = $form->getData(); + + $this->conversationRepository->add($conversation); + + $this->addConversationWithMessages($conversation); + + return new RedirectResponse($this->urlGenerator->generate($redirect, [ + 'id' => $conversation->getId(), + ])); + } + + return new Response( + $this->templatingEngine->render( + $template, + [ + 'form' => $form->createView(), + ] + ) + ); + } + + private function addConversationWithMessages(ConversationInterface $conversation): void + { + if (null === $conversation->getMessages()) { + return; + } + + /** @var MessageInterface $message */ + foreach ($conversation->getMessages()->toArray() as $message) { + $this->messagePersister->createWithConversation( + $conversation->getId(), + $message, + $message->getFile(), + ); + } + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Controller/Messaging/ShowThreadAction.php b/OpenMarketplace/src/Component/Core/Common/Controller/Messaging/ShowThreadAction.php new file mode 100644 index 0000000..d8f5d67 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Controller/Messaging/ShowThreadAction.php @@ -0,0 +1,58 @@ +attributes->get('_sylius')['template']; + + $form = $this->formFactory->create(MessageType::class); + + /** @var Conversation $conversation */ + $conversation = $this->conversationRepository->find($id); + + if (!$this->authorizationChecker->isGranted(ConversationOwningVoter::UPDATE, $conversation)) { + throw new AccessDeniedException(); + } + + return new Response( + $this->templatingEngine->render( + $template, + [ + 'form' => $form->createView(), + 'conversation' => $conversation, + ] + ) + ); + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Controller/Resource/DraftAttributeController.php b/OpenMarketplace/src/Component/Core/Common/Controller/Resource/DraftAttributeController.php new file mode 100644 index 0000000..606c03b --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Controller/Resource/DraftAttributeController.php @@ -0,0 +1,378 @@ +requestConfigurationFactory->create($this->metadata, $request); + + $this->isGrantedOr403($configuration, ResourceActions::UPDATE); + $resource = $this->findOr404($configuration); + $this->denyAccessUnlessGranted(ObjectOwningVoter::OWNIT, $resource); + + $form = $this->resourceFormFactory->create($configuration, $resource); + + $form->handleRequest($request); + if ( + in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'], true) + && $form->isSubmitted() + && $form->isValid() + ) { + $resource = $form->getData(); + $productAttribute = $resource->getProductAttribute(); + if ($productAttribute) { + $this->productAttributeUpdater->update($resource, $productAttribute); + } + + /** @var ResourceControllerEvent $event */ + $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::UPDATE, $configuration, $resource); + + if ($event->isStopped() && !$configuration->isHtmlRequest()) { + throw new HttpException($event->getErrorCode(), $event->getMessage()); + } + if ($event->isStopped()) { + $this->flashHelper->addFlashFromEvent($configuration, $event); + + $eventResponse = $event->getResponse(); + if (null !== $eventResponse) { + return $eventResponse; + } + + return $this->redirectHandler->redirectToResource($configuration, $resource); + } + + try { + $this->resourceUpdateHandler->handle($resource, $configuration, $this->manager); + } catch (UpdateHandlingException $exception) { + if (!$configuration->isHtmlRequest()) { + return $this->createRestView($configuration, $form, $exception->getApiResponseCode()); + } + + $this->flashHelper->addErrorFlash($configuration, $exception->getFlash()); + + return $this->redirectHandler->redirectToReferer($configuration); + } + + if ($configuration->isHtmlRequest()) { + $this->flashHelper->addSuccessFlash($configuration, ResourceActions::UPDATE, $resource); + } + + $postEvent = $this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource); + + if (!$configuration->isHtmlRequest()) { + if ($configuration->getParameters()->get('return_content', false)) { + return $this->createRestView($configuration, $resource, Response::HTTP_OK); + } + + return $this->createRestView($configuration, null, Response::HTTP_NO_CONTENT); + } + + $postEventResponse = $postEvent->getResponse(); + if (null !== $postEventResponse) { + return $postEventResponse; + } + + return $this->redirectHandler->redirectToResource($configuration, $resource); + } + + if (!$configuration->isHtmlRequest()) { + return $this->createRestView($configuration, $form, Response::HTTP_BAD_REQUEST); + } + + $initializeEvent = $this->eventDispatcher->dispatchInitializeEvent(ResourceActions::UPDATE, $configuration, $resource); + $initializeEventResponse = $initializeEvent->getResponse(); + if (null !== $initializeEventResponse) { + return $initializeEventResponse; + } + + return $this->render($configuration->getTemplate(ResourceActions::UPDATE . '.html'), [ + 'configuration' => $configuration, + 'metadata' => $this->metadata, + 'resource' => $resource, + $this->metadata->getName() => $resource, + 'form' => $form->createView(), + ]); + } + + public function createAction(Request $request): Response + { + $configuration = $this->requestConfigurationFactory->create($this->metadata, $request); + + $this->isGrantedOr403($configuration, ResourceActions::CREATE); + + /** + * This three lines uses custom factory to create attribute rest is default Sylius controller + */ + $type = $request->attributes->get('type'); + $currentVendor = $this->vendorProvider->getVendor(); + $newResource = $this->draftAttributeFactory->createTyped($type, $currentVendor); + $form = $this->resourceFormFactory->create($configuration, $newResource); + + $form->handleRequest($request); + + if ($request->isMethod('POST') && $form->isSubmitted() && $form->isValid()) { + $newResource = $form->getData(); + + $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::CREATE, $configuration, $newResource); + + if ($event->isStopped() && !$configuration->isHtmlRequest()) { + throw new HttpException($event->getErrorCode(), $event->getMessage()); + } + if ($event->isStopped()) { + $this->flashHelper->addFlashFromEvent($configuration, $event); + + $eventResponse = $event->getResponse(); + if (null !== $eventResponse) { + return $eventResponse; + } + + return $this->redirectHandler->redirectToIndex($configuration, $newResource); + } + + if ($configuration->hasStateMachine()) { + $stateMachine = $this->getStateMachine(); + $stateMachine->apply($configuration, $newResource); + } + + $this->repository->add($newResource); + + if ($configuration->isHtmlRequest()) { + $this->flashHelper->addSuccessFlash($configuration, ResourceActions::CREATE, $newResource); + } + + $postEvent = $this->eventDispatcher->dispatchPostEvent(ResourceActions::CREATE, $configuration, $newResource); + + if (!$configuration->isHtmlRequest()) { + return $this->createRestView($configuration, $newResource, Response::HTTP_CREATED); + } + + $postEventResponse = $postEvent->getResponse(); + if (null !== $postEventResponse) { + return $postEventResponse; + } + + return $this->redirectHandler->redirectToResource($configuration, $newResource); + } + + if (!$configuration->isHtmlRequest()) { + return $this->createRestView($configuration, $form, Response::HTTP_BAD_REQUEST); + } + + $initializeEvent = $this->eventDispatcher->dispatchInitializeEvent(ResourceActions::CREATE, $configuration, $newResource); + $initializeEventResponse = $initializeEvent->getResponse(); + if (null !== $initializeEventResponse) { + return $initializeEventResponse; + } + + return $this->render($configuration->getTemplate(ResourceActions::CREATE . '.html'), [ + 'configuration' => $configuration, + 'metadata' => $this->metadata, + 'resource' => $newResource, + $this->metadata->getName() => $newResource, + 'form' => $form->createView(), + ]); + } + + /** + * All methods bellow are responsible for render form for different attribute types + */ + public function getAttributeTypesAction(Request $request, string $template): Response + { + /** @var ServiceRegistryInterface $serviceRegistry */ + $serviceRegistry = $this->get('sylius.registry.attribute_type'); + + return $this->render( + $template, + [ + 'types' => $serviceRegistry->all(), + 'metadata' => $this->metadata, + ] + ); + } + + public function renderAttributesAction(Request $request): Response + { + /** @var FormFactoryInterface $formFactory */ + $formFactory = $this->get('form.factory'); + + $template = $request->attributes->get('template', '@SyliusAttribute/attributeChoice.html.twig'); + + $form = $formFactory->create(DraftAttributeChoiceType::class, null, [ + 'multiple' => true, + ]); + + return $this->render($template, ['form' => $form->createView()]); + } + + public function renderAttributeValueFormsAction(Request $request): Response + { + /** @var FormFactoryInterface $formFactory */ + $formFactory = $this->get('form.factory'); + + $template = $request->attributes->get('template', '@SyliusAttribute/attributeValueForms.html.twig'); + + $form = $formFactory->create(DraftAttributeChoiceType::class, null, [ + 'multiple' => true, + ]); + $form->handleRequest($request); + + $attributes = $form->getData(); + if (null === $attributes) { + throw new BadRequestHttpException(); + } + + /** @var TranslationLocaleProviderInterface $localeProvider */ + $localeProvider = $this->get('sylius.translation_locale_provider'); + $localeCodes = $localeProvider->getDefinedLocalesCodes(); + + $forms = []; + foreach ($attributes as $attribute) { + $forms[$attribute->getCode()] = $this->getAttributeFormsInAllLocales($attribute, $localeCodes); + } + + return $this->render($template, [ + 'forms' => $forms, + 'count' => $request->query->get('count'), + 'metadata' => $this->metadata, + ]); + } + + /** + * @param array|string[] $localeCodes + * + * @return array|FormView[] + */ + protected function getAttributeFormsInAllLocales(AttributeInterface $attribute, array $localeCodes): array + { + /** @var FormTypeRegistry $formRegistry */ + $formRegistry = $this->get('sylius.form_registry.attribute_type'); + + /** @var string $type */ + $type = $attribute->getType(); + + /** @var string $attributeForm */ + $attributeForm = $formRegistry->get($type, 'default'); + + $forms = []; + + if (!$attribute->isTranslatable()) { + array_push($localeCodes, null); + + return [null => $this->createFormAndView($attributeForm, $attribute)]; + } + + foreach ($localeCodes as $localeCode) { + $forms[$localeCode] = $this->createFormAndView($attributeForm, $attribute); + } + + return $forms; + } + + private function createFormAndView( + string $attributeForm, + AttributeInterface $attribute + ): FormView { + /** @var FormFactoryInterface $formFactory */ + $formFactory = $this->get('form.factory'); + + return $formFactory + ->createNamed( + 'value', + $attributeForm, + null, + ['label' => $attribute->getName(), 'configuration' => $attribute->getConfiguration()] + ) + ->createView(); + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Controller/Resource/OrderController.php b/OpenMarketplace/src/Component/Core/Common/Controller/Resource/OrderController.php new file mode 100644 index 0000000..f51787d --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Controller/Resource/OrderController.php @@ -0,0 +1,194 @@ +requestConfigurationFactory->create($this->metadata, $request); + + $this->isGrantedOr403($configuration, ResourceActions::INDEX); + $resources = $this->resourcesCollectionProvider->get($configuration, $this->repository); + + $this->eventDispatcher->dispatchMultiple(ResourceActions::INDEX, $configuration, $resources); + + if ($configuration->isHtmlRequest()) { + return $this->render($configuration->getTemplate(ResourceActions::INDEX . '.html'), [ + 'configuration' => $configuration, + 'metadata' => $this->metadata, + 'resources' => $resources, + $this->metadata->getPluralName() => $resources, + ]); + } + + return $this->createRestView($configuration, $resources); + } + + public function showAction(Request $request): Response + { + $configuration = $this->requestConfigurationFactory->create($this->metadata, $request); + + $this->isGrantedOr403($configuration, ResourceActions::SHOW); + + /** @var OrderInterface $resource */ + $resource = $this->findOr404($configuration); + + if (null === $resource->getPrimaryOrder()) { + return $this->redirectToRoute('open_marketplace_vendor_orders_listing'); + } + + $this->eventDispatcher->dispatch(ResourceActions::SHOW, $configuration, $resource); + + if ($configuration->isHtmlRequest()) { + return $this->render($configuration->getTemplate(ResourceActions::SHOW . '.html'), [ + 'configuration' => $configuration, + 'metadata' => $this->metadata, + 'resource' => $resource, + 'form' => $this->createForm(ShipmentShipType::class)->createView(), + $this->metadata->getName() => $resource, + ]); + } + + return $this->createRestView($configuration, $resource); + } + + public function updateAction(Request $request): Response + { + $configuration = $this->requestConfigurationFactory->create($this->metadata, $request); + + $this->isGrantedOr403($configuration, ResourceActions::UPDATE); + $resource = $this->findOr404($configuration); + + $form = $this->resourceFormFactory->create($configuration, $resource); + $form->handleRequest($request); + + if ( + in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'], true) + && $form->isSubmitted() + && $form->isValid() + ) { + $resource = $form->getData(); + + /** @var ResourceControllerEvent $event */ + $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::UPDATE, $configuration, $resource); + + if ($event->isStopped() && !$configuration->isHtmlRequest()) { + throw new HttpException($event->getErrorCode(), $event->getMessage()); + } + if ($event->isStopped()) { + $this->flashHelper->addFlashFromEvent($configuration, $event); + + $eventResponse = $event->getResponse(); + if (null !== $eventResponse) { + return $eventResponse; + } + + return $this->redirectHandler->redirectToResource($configuration, $resource); + } + + try { + $splitOrderByVendorProcessor = $this->container->get('bitbag.open_marketplace.component.order.processor.split_order_by_vendor'); + $orders = $splitOrderByVendorProcessor->process($resource); + + foreach ($orders as $order) { + $this->resourceUpdateHandler->handle($order, $configuration, $this->manager); + } + } catch (UpdateHandlingException $exception) { + if (!$configuration->isHtmlRequest()) { + return $this->createRestView($configuration, $form, $exception->getApiResponseCode()); + } + + $this->flashHelper->addErrorFlash($configuration, $exception->getFlash()); + + return $this->redirectHandler->redirectToReferer($configuration); + } + + if ($configuration->isHtmlRequest()) { + $this->flashHelper->addSuccessFlash($configuration, ResourceActions::UPDATE, $resource); + } + + $postEvent = $this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource); + + if (!$configuration->isHtmlRequest()) { + if ($configuration->getParameters()->get('return_content', false)) { + return $this->createRestView($configuration, $resource, Response::HTTP_OK); + } + + return $this->createRestView($configuration, null, Response::HTTP_NO_CONTENT); + } + + $postEventResponse = $postEvent->getResponse(); + if (null !== $postEventResponse) { + return $postEventResponse; + } + + return $this->redirectHandler->redirectToResource($configuration, $resource); + } + + if (!$configuration->isHtmlRequest()) { + return $this->createRestView($configuration, $form, Response::HTTP_BAD_REQUEST); + } + + $initializeEvent = $this->eventDispatcher->dispatchInitializeEvent(ResourceActions::UPDATE, $configuration, $resource); + $initializeEventResponse = $initializeEvent->getResponse(); + if (null !== $initializeEventResponse) { + return $initializeEventResponse; + } + + return $this->render($configuration->getTemplate(ResourceActions::UPDATE . '.html'), [ + 'configuration' => $configuration, + 'metadata' => $this->metadata, + 'resource' => $resource, + $this->metadata->getName() => $resource, + 'form' => $form->createView(), + ]); + } + + public function thankYouAction(Request $request): Response + { + $configuration = $this->requestConfigurationFactory->create($this->metadata, $request); + + $orderId = $request->getSession()->get('sylius_order_id', null); + + if (null === $orderId) { + $options = $configuration->getParameters()->get('after_failure'); + + return $this->redirectHandler->redirectToRoute( + $configuration, + $options['route'] ?? 'sylius_shop_homepage', + $options['parameters'] ?? [] + ); + } + + $request->getSession()->remove('sylius_order_id'); + $order = $this->repository->find($orderId); + Assert::notNull($order); + + return $this->render( + $configuration->getParameters()->get('template'), + [ + 'order' => $order, + ] + ); + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Controller/Resource/VendorController.php b/OpenMarketplace/src/Component/Core/Common/Controller/Resource/VendorController.php new file mode 100644 index 0000000..61c3c65 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Controller/Resource/VendorController.php @@ -0,0 +1,180 @@ +redirectToRoute('sylius_shop_login'); + } catch (TokenNotFoundException $exception) { + return $this->redirectToRoute('sylius_shop_login'); + } + } + + public function customUpdateAction(Request $request): Response + { + $configuration = $this->requestConfigurationFactory->create($this->metadata, $request); + $this->isGrantedOr403($configuration, ResourceActions::UPDATE); + + $vendor = $this->container->get('bitbag.open_marketplace.component.vendor.context.vendor')->getVendor(); + $pendingUpdate = $this->manager->getRepository(ProfileUpdate::class) + ->findOneBy(['vendor' => $vendor]); + + if (null !== $pendingUpdate) { + $this->addFlash('error', 'sylius.user.verify_email_request'); + + return $this->redirectToRoute('open_marketplace_vendor_profile_details'); + } + + $resource = $vendor; + + $form = $this->resourceFormFactory->create($configuration, $resource); + + $form->handleRequest($request); + if ( + in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'], true) + && $form->isSubmitted() + && $form->isValid() + ) { + $resource = $form->getData(); + + try { + $image = $resource->getImage(); + $backgroundImage = $resource->getBackgroundImage(); + $this->container->get('bitbag.open_marketplace.component.vendor.profile_updater')->createPendingVendorProfileUpdate( + $form->getData(), + $vendor, + $image, + $backgroundImage + ); + if ($image) { + $this->manager->remove($image); + } + if ($backgroundImage) { + $this->manager->remove($backgroundImage); + } + + $vendor->setEditedAt(new \DateTime()); + $this->manager->flush(); + } catch (UpdateHandlingException $exception) { + if (!$configuration->isHtmlRequest()) { + return $this->createRestView($configuration, $form, $exception->getApiResponseCode()); + } + + $this->flashHelper->addErrorFlash($configuration, $exception->getFlash()); + + return $this->redirectHandler->redirectToReferer($configuration); + } + + if ($configuration->isHtmlRequest()) { + $this->flashHelper->addSuccessFlash($configuration, ResourceActions::UPDATE, $resource); + } + + if (!$configuration->isHtmlRequest()) { + if ($configuration->getParameters()->get('return_content', false)) { + return $this->createRestView($configuration, $resource, Response::HTTP_OK); + } + + return $this->createRestView($configuration, null, Response::HTTP_NO_CONTENT); + } + + return $this->redirectHandler->redirectToResource($configuration, $resource); + } + + if (!$configuration->isHtmlRequest()) { + return $this->createRestView($configuration, $form, Response::HTTP_BAD_REQUEST); + } + + return $this->render($configuration->getTemplate(ResourceActions::UPDATE . '.html'), [ + 'configuration' => $configuration, + 'metadata' => $this->metadata, + 'resource' => $resource, + $this->metadata->getName() => $resource, + 'form' => $form->createView(), + ]); + } + + public function showVendorProfileAction(Request $request): Response + { + $configuration = $this->requestConfigurationFactory->create($this->metadata, $request); + + $this->isGrantedOr403($configuration, ResourceActions::SHOW); + + /** @var ResourceInterface $resource */ + $resource = $this->container->get('bitbag.open_marketplace.component.vendor.context.vendor')->getVendor(); + $this->eventDispatcher->dispatch(ResourceActions::SHOW, $configuration, $resource); + + if ($configuration->isHtmlRequest()) { + return $this->render($configuration->getTemplate(ResourceActions::SHOW . '.html'), [ + 'configuration' => $configuration, + 'metadata' => $this->metadata, + 'resource' => $resource, + $this->metadata->getName() => $resource, + ]); + } + + return $this->createRestView($configuration, $resource); + } + + public function verifyVendorAction(Request $request): Response + { + $vendorId = $request->attributes->get('id', 0); + $vendorRepository = $this->manager->getRepository(Vendor::class); + + $currentVendor = $vendorRepository->findOneBy(['id' => $vendorId]); + + if (null === $currentVendor) { + throw new NotFoundHttpException(sprintf('Vendor with id %d has not been found', $vendorId)); + } + + $currentVendor->setStatus(VendorInterface::STATUS_VERIFIED); + + $this->manager->flush(); + + $this->addFlash('success', 'open_marketplace.ui.vendor_verified'); + + return $this->redirectToRoute('open_marketplace_admin_vendor_index'); + } + + public function enablingVendorAction(Request $request): Response + { + $vendorId = $request->attributes->get('id', 0); + $vendorRepository = $this->manager->getRepository(Vendor::class); + $currentVendor = $vendorRepository->findOneBy(['id' => $vendorId]); + if ($currentVendor) { + $currentVendor->setEnabled(!$currentVendor->isEnabled()); + $messageSuffix = $currentVendor->isEnabled() ? 'enabled' : 'disabled'; + + $this->manager->flush(); + $this->addFlash('success', 'open_marketplace.ui.vendor_' . $messageSuffix); + } + + return $this->redirectToRoute('open_marketplace_admin_vendor_index'); + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Fixture/AttributeFixture.php b/OpenMarketplace/src/Component/Core/Common/Fixture/AttributeFixture.php new file mode 100644 index 0000000..a22f977 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Fixture/AttributeFixture.php @@ -0,0 +1,66 @@ +attributeExampleFactory->create($attributeData); + $this->attributeManager->persist($attribute); + + if (0 === ($i % 50)) { + $this->attributeManager->flush(); + } + + ++$i; + } + + $this->attributeManager->flush(); + } + + protected function configureOptionsNode(ArrayNodeDefinition $optionsNode): void + { + $optionsNode + ->children() + ->arrayNode('custom') + ->arrayPrototype() + ->children() + ->scalarNode('vendor')->end() + ->scalarNode('code')->end() + ->scalarNode('name')->end() + ->scalarNode('type')->end() + ->end() + ->end() + ->end() + ->end() + ; + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Fixture/ConversationCategoryFixture.php b/OpenMarketplace/src/Component/Core/Common/Fixture/ConversationCategoryFixture.php new file mode 100644 index 0000000..1dd13b4 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Fixture/ConversationCategoryFixture.php @@ -0,0 +1,56 @@ +conversationCategoryFactory->createNew(); + + $category->setName($categoryName); + + $this->conversationCategoryManager->persist($category); + } + + $this->conversationCategoryManager->flush(); + } + + public function getName(): string + { + return 'conversation_category'; + } + + protected function configureOptionsNode(ArrayNodeDefinition $optionsNode): void + { + $optionsNode + ->children() + ->arrayNode('categories')->scalarPrototype()->end() + ; + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Fixture/ConversationFixture.php b/OpenMarketplace/src/Component/Core/Common/Fixture/ConversationFixture.php new file mode 100644 index 0000000..1fa3f84 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Fixture/ConversationFixture.php @@ -0,0 +1,22 @@ +shopUserRepository->findOneBy(['username' => $options['vendor']]); + Assert::notNull($shopUser); + + /** @var VendorInterface $vendor */ + $vendor = $shopUser->getVendor(); + Assert::notNull($vendor); + + $attribute = $this->draftAttributeFactory->createTyped( + $options['type'], + $vendor + ); + $attribute->setCode($options['code']); + + foreach ($this->getLocales() as $locale) { + $translation = new DraftAttributeTranslation(); + $translation->setName($options['name']); + $translation->setLocale($locale); + $translation->setTranslatable($attribute); + } + + return $attribute; + } + + private function getLocales(): iterable + { + /** @var LocaleInterface[] $locales */ + $locales = $this->localeRepository->findAll(); + foreach ($locales as $locale) { + yield $locale->getCode(); + } + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Fixture/Factory/ConversationExampleFactory.php b/OpenMarketplace/src/Component/Core/Common/Fixture/Factory/ConversationExampleFactory.php new file mode 100644 index 0000000..9ee4735 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Fixture/Factory/ConversationExampleFactory.php @@ -0,0 +1,91 @@ +faker = Factory::create(); + $this->optionsResolver = new OptionsResolver(); + + $this->configureOptions($this->optionsResolver); + } + + protected function configureOptions(OptionsResolver $resolver): void + { + $resolver + ->setDefault('number_of_messages', fn (Options $options): int => random_int(4, 10)) + ->setDefault('vendor', LazyOption::randomOne($this->vendorRepository)) + ->setDefault('admin_user', LazyOption::randomOne($this->adminUserRepository)) + ->setDefault('category', LazyOption::randomOne($this->categoryRepository)); + } + + public function create(array $options = []): ConversationInterface + { + $options = $this->optionsResolver->resolve($options); + + /** @var VendorInterface $vendor */ + $vendor = $options['vendor']; + + /** @var ConversationInterface $conversation */ + $conversation = $this->conversationFactory->createNew(); + $conversation->setShopUser($vendor->getShopUser()); + $conversation->setCategory($options['category']); + $this->createMessages($conversation, $options['admin_user'], $vendor->getShopUser(), $options['number_of_messages']); + + return $conversation; + } + + private function createMessages( + ConversationInterface $conversation, + AdminUserInterface $adminUser, + ShopUserInterface $shopUser, + int $numberOfMessages + ): void { + $conversationUsers = [$adminUser, $shopUser]; + for ($i = 0; $i < $numberOfMessages; ++$i) { + /** @var MessageInterface $message */ + $message = $this->conversationMessageFactory->createNew(); + $message->setAuthor($this->faker->randomElement($conversationUsers)); + $message->setContent($this->faker->sentence); + $message->setConversation($conversation); + $conversation->addMessage($message); + } + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Fixture/Factory/OrderExampleFactory.php b/OpenMarketplace/src/Component/Core/Common/Fixture/Factory/OrderExampleFactory.php new file mode 100644 index 0000000..4108217 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Fixture/Factory/OrderExampleFactory.php @@ -0,0 +1,388 @@ +optionsResolver = new OptionsResolver(); + $this->faker = Factory::create(); + $this->configureOptions($this->optionsResolver); + } + + public function create(array $options = []): OrderInterface + { + $options = $this->optionsResolver->resolve($options); + + return $this->createOrder($options['channel'], $options['customer'], $options['country'], $options['complete_date']); + } + + public function createArray(array $options = []): array + { + $options = $this->optionsResolver->resolve($options); + + $orders = $this->createOrders($options['channel'], $options['customer'], $options['country'], $options['complete_date']); + foreach ($orders as $order) { + $this->setOrderCompletedDate($order, $options['complete_date']); + if ($options['fulfilled']) { + $this->fulfillOrder($order); + } + } + + return $orders; + } + + public function createOrderWithTotalAmount( + ChannelInterface $channel, + VendorInterface $vendor, + CustomerInterface $customer, + int $totalAmount + ): OrderInterface { + $order = $this->orderFactory->createNew(); + $localeCode = $this->faker->randomElement($channel->getLocales()->toArray())->getCode(); + $order->setCurrencyCode($channel->getBaseCurrency()?->getCode()); + $order->setLocaleCode($localeCode); + $order->setChannel($channel); + $order->setCustomer($customer); + $order->setVendor($vendor); + $this->generateItemForTotalAmount($order, $totalAmount); + + return $order; + } + + protected function configureOptions(OptionsResolver $resolver): void + { + $resolver + ->setDefault('amount', 20) + + ->setDefault('channel', LazyOption::randomOne($this->channelRepository)) + ->setAllowedTypes('channel', ['null', 'string', ChannelInterface::class]) + ->setNormalizer('channel', LazyOption::getOneBy($this->channelRepository, 'code')) + + ->setDefault('customer', LazyOption::randomOne($this->customerRepository)) + ->setAllowedTypes('customer', ['null', 'string', CustomerInterface::class]) + ->setNormalizer('customer', LazyOption::getOneBy($this->customerRepository, 'email')) + + ->setDefault('country', LazyOption::randomOne($this->countryRepository)) + ->setAllowedTypes('country', ['null', 'string', CountryInterface::class]) + ->setNormalizer('country', LazyOption::findOneBy($this->countryRepository, 'code')) + + ->setDefault('complete_date', fn (Options $options): \DateTimeInterface => $this->faker->dateTimeBetween('-1 years', 'now')) + ->setAllowedTypes('complete_date', ['null', \DateTime::class]) + + ->setDefault('fulfilled', false) + ->setAllowedTypes('fulfilled', ['bool']) + ; + } + + protected function createOrder( + ChannelInterface $channel, + CustomerInterface $customer, + CountryInterface $country, + \DateTimeInterface $createdAt + ): OrderInterface { + $countryCode = $country->getCode(); + + $currencyCode = $channel->getBaseCurrency()?->getCode(); + $localeCode = $this->faker->randomElement($channel->getLocales()->toArray())->getCode(); + + $order = $this->orderFactory->createNew(); + $order->setChannel($channel); + $order->setCustomer($customer); + $order->setCurrencyCode($currencyCode); + $order->setLocaleCode($localeCode); + + $this->generateItems($order); + + $this->address($order, $countryCode); + $this->selectShipping($order, $createdAt); + $this->selectPayment($order, $createdAt); + + return $order; + } + + protected function createOrders( + ChannelInterface $channel, + CustomerInterface $customer, + CountryInterface $country, + \DateTimeInterface $createdAt + ): array { + $order = $this->createOrder($channel, $customer, $country, $createdAt); + + return $this->completeCheckout($order); + } + + protected function generateItems(OrderInterface $order): void + { + $numberOfItems = random_int(1, 5); + $channel = $order->getChannel(); + $locale = $order->getLocaleCode(); + if (null === $channel || null === $locale) { + throw new \InvalidArgumentException('Order has no channel or locale code'); + } + + $products = $this->productRepository->findLatestByChannel($channel, $locale, 100); + if (0 === count($products)) { + throw new \InvalidArgumentException(sprintf( + 'You have no enabled products at the channel "%s", but they are required to create an orders for that channel', + $channel->getCode(), + )); + } + + $generatedItems = []; + + for ($i = 0; $i < $numberOfItems; ++$i) { + /** @var ProductInterface $product */ + $product = $this->faker->randomElement($products); + $variant = $this->faker->randomElement($product->getVariants()->toArray()); + $variant->setCurrentLocale($order->getLocaleCode()); + + if (array_key_exists($variant->getCode(), $generatedItems)) { + /** @var OrderItemInterface $item */ + $item = $generatedItems[$variant->getCode()]; + $this->orderItemQuantityModifier->modify($item, $item->getQuantity() + random_int(1, 5)); + + continue; + } + + $item = $this->orderItemFactory->createNew(); + + $item->setVariant($variant); + $this->orderItemQuantityModifier->modify($item, random_int(1, 5)); + + $generatedItems[$variant->getCode()] = $item; + $order->addItem($item); + } + } + + protected function address(OrderInterface $order, ?string $countryCode): void + { + /** @var AddressInterface $address */ + $address = $this->addressFactory->createNew(); + $address->setFirstName($this->faker->firstName); + $address->setLastName($this->faker->lastName); + $address->setStreet($this->faker->streetAddress); + $address->setCountryCode($countryCode); + $address->setCity($this->faker->city); + $address->setPostcode($this->faker->postcode); + + $order->setShippingAddress($address); + $order->setBillingAddress(clone $address); + + $this->applyCheckoutStateTransition($order, OrderCheckoutTransitions::TRANSITION_ADDRESS); + } + + protected function selectShipping(OrderInterface $order, \DateTimeInterface $createdAt): void + { + if (OrderCheckoutStates::STATE_SHIPPING_SKIPPED === $order->getCheckoutState()) { + return; + } + + $channel = $order->getChannel(); + if (null === $channel) { + throw new \InvalidArgumentException('Order has no channel'); + } + + $shippingMethods = $this->shippingMethodRepository->findEnabledForChannel($channel); + + if (0 === count($shippingMethods)) { + throw new \InvalidArgumentException(sprintf( + 'You have no shipping method available for the channel with code "%s", but they are required to proceed an order', + $channel->getCode(), + )); + } + + $shippingMethod = $this->faker->randomElement($shippingMethods); + + /** @var ChannelInterface $channel */ + $channel = $order->getChannel(); + Assert::notNull($shippingMethod, $this->generateInvalidSkipMessage('shipping', $channel->getCode())); + + foreach ($order->getShipments() as $shipment) { + $shipment->setMethod($shippingMethod); + $shipment->setCreatedAt($createdAt); + } + + $this->applyCheckoutStateTransition($order, OrderCheckoutTransitions::TRANSITION_SELECT_SHIPPING); + } + + protected function selectPayment(OrderInterface $order, \DateTimeInterface $createdAt): void + { + if (OrderCheckoutStates::STATE_PAYMENT_SKIPPED === $order->getCheckoutState()) { + return; + } + + $channel = $order->getChannel(); + if (null === $channel) { + throw new \InvalidArgumentException('Order has no channel'); + } + + $paymentMethod = $this + ->faker + ->randomElement($this->paymentMethodRepository->findEnabledForChannel($channel)) + ; + + Assert::notNull($paymentMethod, $this->generateInvalidSkipMessage('payment', $channel->getCode())); + + foreach ($order->getPayments() as $payment) { + $payment->setMethod($paymentMethod); + $payment->setCreatedAt($createdAt); + } + + $this->applyCheckoutStateTransition($order, OrderCheckoutTransitions::TRANSITION_SELECT_PAYMENT); + } + + protected function completeCheckout(OrderInterface $order): array + { + if ($this->faker->boolean(25)) { + $order->setNotes($this->faker->sentence); + } + $this->orderManager->persist($order); + + $ordersFromSplit = $this->splitOrderByVendorProcessor->process($order); + + foreach ($ordersFromSplit as $orderFromSplit) { + $this->applyCheckoutStateTransition($orderFromSplit, OrderCheckoutTransitions::TRANSITION_COMPLETE); + } + $this->orderManager->flush(); + + return $ordersFromSplit; + } + + protected function applyCheckoutStateTransition(OrderInterface $order, string $transition): void + { + $this->stateMachineFactory->get($order, OrderCheckoutTransitions::GRAPH)->apply($transition); + } + + protected function generateInvalidSkipMessage(string $type, ?string $channelCode): string + { + return sprintf( + "No enabled %s method was found for the channel '%s'. " . + "Set 'skipping_%s_step_allowed' option to true for this channel if you want to skip %s method selection.", + $type, + $channelCode, + $type, + $type, + ); + } + + protected function setOrderCompletedDate(OrderInterface $order, \DateTimeInterface $date): void + { + if (OrderCheckoutStates::STATE_COMPLETED === $order->getCheckoutState()) { + $order->setCheckoutCompletedAt($date); + } + } + + protected function fulfillOrder(OrderInterface $order): void + { + $this->completePayments($order); + $this->completeShipments($order); + } + + protected function completePayments(OrderInterface $order): void + { + foreach ($order->getPayments() as $payment) { + $stateMachine = $this->stateMachineFactory->get($payment, PaymentTransitions::GRAPH); + if ($stateMachine->can(PaymentTransitions::TRANSITION_COMPLETE)) { + $stateMachine->apply(PaymentTransitions::TRANSITION_COMPLETE); + } + } + } + + protected function completeShipments(OrderInterface $order): void + { + foreach ($order->getShipments() as $shipment) { + $stateMachine = $this->stateMachineFactory->get($shipment, ShipmentTransitions::GRAPH); + if ($stateMachine->can(ShipmentTransitions::TRANSITION_SHIP)) { + $stateMachine->apply(ShipmentTransitions::TRANSITION_SHIP); + } + } + } + + private function generateItemForTotalAmount(OrderInterface $order, int $totalAmount): void + { + $channel = $order->getChannel(); + $locale = $order->getLocaleCode(); + if (null === $channel || null === $locale) { + throw new \InvalidArgumentException('Order has no channel or locale code'); + } + + /** @var ProductInterface $product */ + $product = $this->productRepository->findLatestByChannel($channel, $locale, 1)[0]; + + /** @var ProductVariantInterface $variant */ + $variant = $product->getVariants()->first(); + + /** @var ChannelPricingInterface $pricing */ + $pricing = $variant->getChannelPricingForChannel($channel); + $pricing->setPrice($totalAmount); + + $variant->setCurrentLocale($locale); + $item = $this->orderItemFactory->createNew(); + $item->setUnitPrice($totalAmount); + $item->setVariant($variant); + $this->orderItemQuantityModifier->modify($item, 1); + + $order->addItem($item); + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Fixture/Factory/OrderExampleFactoryInterface.php b/OpenMarketplace/src/Component/Core/Common/Fixture/Factory/OrderExampleFactoryInterface.php new file mode 100644 index 0000000..286035b --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Fixture/Factory/OrderExampleFactoryInterface.php @@ -0,0 +1,30 @@ +faker = Factory::create(); + } + + public function create(array $options = []): DraftInterface + { + /** @var DraftInterface $productDraft */ + $productDraft = $this->productDraftFactory->createNew(); + + $productDraft->setCode($options['code']); + + /** @var ShopUserInterface $shopUser */ + $shopUser = $this->shopUserRepository->findOneBy(['username' => $options['vendor']]); + Assert::notNull($shopUser); + + /** @var VendorInterface $vendor */ + $vendor = $shopUser->getVendor(); + Assert::notNull($vendor); + + $this->listingPersister->createNewProductListing($productDraft, $vendor); + + /** @var ChannelInterface $channel */ + foreach ($this->channelRepository->findAll() as $channel) { + $code = $channel->getCode(); + if (null === $code) { + continue; + } + + $productDraft->addChannel($channel); + $this->createProductListingPricing($productDraft, $code); + } + + $this->createTranslations($productDraft, $options); + $this->createAttributes($productDraft, $vendor, $options); + $this->createRandomImage($productDraft, $options); + $this->attachToTaxons($productDraft, $options); + + $this->productDraftStateMachineTransition->applyIfCan($productDraft, DraftTransitions::TRANSITION_SEND_TO_VERIFICATION); + $this->productDraftStateMachineTransition->applyIfCan($productDraft, DraftTransitions::TRANSITION_ACCEPT); + + return $productDraft; + } + + private function createProductListingPricing(DraftInterface $productDraft, string $channelCode): void + { + /** @var ListingPriceInterface $productListingPrice */ + $productListingPrice = $this->productListingPriceFactory->createNew(); + $productListingPrice->setChannelCode($channelCode); + $productListingPrice->setPrice($this->faker->numberBetween(100, 10000)); + $productListingPrice->setOriginalPrice($this->faker->numberBetween(100, 10000)); + $productListingPrice->setMinimumPrice(0); + $productListingPrice->setProductDraft($productDraft); + + $productDraft->addProductListingPrice($productListingPrice); + } + + private function createTranslations(DraftInterface $productDraft, array $options): void + { + foreach ($this->getLocales() as $localeCode) { + /** @var DraftTranslationInterface $productDraftTranslation */ + $productDraftTranslation = $this->productTranslationFactory->createNew(); + $productDraftTranslation->setLocale($localeCode); + $productDraftTranslation->setName($options['name']); + $productDraftTranslation->setSlug($this->slugGenerator->generate($options['name'])); + + /** @var string $description */ + $description = $this->faker->paragraphs(3, true); + $productDraftTranslation->setDescription($description); + + /** @var string $shortDescription */ + $shortDescription = $this->faker->paragraphs(1, true); + $shortDescription = substr($shortDescription, 0, 254) . '.'; + $productDraftTranslation->setShortDescription($shortDescription); + $productDraftTranslation->setMetaDescription(null); + $productDraftTranslation->setMetaKeywords(null); + $productDraftTranslation->setProductDraft($productDraft); + $productDraft->addTranslation($productDraftTranslation); + } + } + + private function createAttributes( + DraftInterface $productDraft, + VendorInterface $vendor, + array $options + ): void { + if (!isset($options['attributes'])) { + return; + } + + foreach ($options['attributes'] as $attributeData) { + /** @var DraftAttributeInterface $attribute */ + $attribute = $this->draftAttributeRepository->findOneBy([ + 'code' => $attributeData['code'], + 'vendor' => $vendor->getId(), + ]); + + $attributeValue = new DraftAttributeValue(); + $attributeValue->setAttribute($attribute); + $attributeValue->setSubject($productDraft); + $attributeValue->setValue($attributeData['value']); + + $productDraft->addAttribute($attributeValue); + } + } + + private function getLocales(): iterable + { + /** @var LocaleInterface[] $locales */ + $locales = $this->localeRepository->findAll(); + foreach ($locales as $locale) { + yield $locale->getCode(); + } + } + + private function createRandomImage(DraftInterface $product, array $options): void + { + if (!count($options['images'])) { + return; + } + + $i = 0; + foreach ($options['images'] as $imagePath) { + $imageType = 0 === $i ? 'main' : ''; + + /** @var string $imagePath */ + $imagePath = $this->fileLocator->locate($imagePath); + $uploadedImage = new UploadedFile($imagePath, basename($imagePath)); + + /** @var ImageInterface $productImage */ + $productImage = $this->draftImageFactory->createNew(); + $productImage->setFile($uploadedImage); + $productImage->setType($imageType); + + $this->imageUploader->upload($productImage); + + $product->addImage($productImage); + $productImage->setOwner($product); + + ++$i; + } + } + + private function attachToTaxons(DraftInterface $productDraft, array $options): void + { + if (isset($options['main_taxon'])) { + /** @var TaxonInterface $taxon */ + $taxon = $this->taxonRepository->findOneBy(['code' => $options['main_taxon']]); + $productDraft->setMainTaxon($taxon); + } + + if (!isset($options['taxons'])) { + return; + } + + foreach ($options['taxons'] as $taxonCode) { + /** @var TaxonInterface $taxon */ + $taxon = $this->taxonRepository->findOneBy(['code' => $taxonCode]); + + $productDraftTaxon = new DraftTaxon(); + $productDraftTaxon->setProductDraft($productDraft); + $productDraftTaxon->setTaxon($taxon); + + $productDraft->addProductDraftTaxon($productDraftTaxon); + } + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Fixture/Factory/SettlementExampleFactory.php b/OpenMarketplace/src/Component/Core/Common/Fixture/Factory/SettlementExampleFactory.php new file mode 100644 index 0000000..c2a60e2 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Fixture/Factory/SettlementExampleFactory.php @@ -0,0 +1,120 @@ +optionsResolver = new OptionsResolver(); + $this->configureOptions($this->optionsResolver); + } + + public function create(array $options = []): SettlementInterface + { + $options = $this->optionsResolver->resolve($options); + $vendor = $this->getVendor($options); + $channel = $this->getChannel($options); + [$from, $to] = $this->getPeriod($options, $vendor); + + $settlement = $this->settlementFactory->createNewForVendorAndChannel( + $vendor, + $channel, + $options['totalAmount'], + $options['totalCommissionAmount'], + $from, + $to + ); + + $settlement->setStatus($options['status']); + + return $settlement; + } + + protected function configureOptions(OptionsResolver $resolver): void + { + $resolver + ->setDefault('vendor', LazyOption::randomOne($this->shopUserRepository)) + ->setAllowedTypes('vendor', ['string', VendorInterface::class]) + ->setDefault('status', SettlementInterface::STATUS_NEW) + ->setAllowedValues('status', SettlementInterface::AVAILABLE_STATUSES) + ->setDefault('totalAmount', random_int(100, 10000)) + ->setAllowedTypes('totalAmount', ['int']) + ->setDefault('totalCommissionAmount', random_int(10, 100)) + ->setAllowedTypes('totalCommissionAmount', ['int']) + ->setDefault('channel', LazyOption::randomOne($this->channelRepository)) + ->setDefault('startDate', null) + ->setDefault('endDate', null) + ; + } + + private function getVendor(array $options): VendorInterface + { + $vendor = $options['vendor']; + if ($vendor instanceof VendorInterface) { + return $vendor; + } + + $shopUser = $this->shopUserRepository->findOneBy(['username' => $vendor]); + Assert::isInstanceOf($shopUser, ShopUserInterface::class); + + $vendor = $shopUser->getVendor(); + Assert::isInstanceOf($vendor, VendorInterface::class); + + return $vendor; + } + + private function getChannel(array $options): ChannelInterface + { + $channel = $options['channel']; + + if ($channel instanceof ChannelInterface) { + return $channel; + } + + $channel = $this->channelRepository->findOneBy(['code' => $options['channel']]); + Assert::isInstanceOf($channel, ChannelInterface::class); + + return $channel; + } + + private function getPeriod(array $options, VendorInterface $vendor): array + { + $from = $options['startDate']; + $to = $options['endDate']; + + if (null !== $from && null !== $to) { + return [$from, $to]; + } + + return $this->settlementPeriodResolver->getSettlementDateRangeForVendor($vendor, true); + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Fixture/Factory/VendorExampleFactory.php b/OpenMarketplace/src/Component/Core/Common/Fixture/Factory/VendorExampleFactory.php new file mode 100644 index 0000000..1edd15b --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Fixture/Factory/VendorExampleFactory.php @@ -0,0 +1,210 @@ +faker = Factory::create(); + $this->optionsResolver = new OptionsResolver(); + $this->configureOptions($this->optionsResolver); + } + + public function create(array $options = []): VendorInterface + { + $this->countryCheck(); + + $options = $this->optionsResolver->resolve($options); + + /** @var CustomerInterface $customer */ + $customer = $this->customerFactory->createNew(); + $customer->setEmail($options['email']); + $customer->setFirstName($options['first_name']); + $customer->setLastName($options['last_name']); + $customer->setGroup($options['customer_group']); + $customer->setGender($options['gender']); + $customer->setPhoneNumber($options['phone_number']); + $customer->setBirthday($options['birthday']); + + /** @var ShopUserInterface $user */ + $user = $this->shopUserFactory->createNew(); + $user->setPlainPassword($options['password']); + $user->setEnabled($options['enabled']); + $user->addRole('ROLE_USER'); + $user->setCustomer($customer); + + $vendorAddress = $this->addressFactory->createAddress($options['street'], $options['city'], $options['postcode'], $options['country']); + + /** @var VendorInterface $vendor */ + $vendor = $this->profileFactory->createNew(); + $vendor->setCompanyName($options['company_name']); + $vendor->setTaxIdentifier($options['tax_identifier']); + $vendor->setBankAccountNumber($options['bank_account_number']); + $vendor->setPhoneNumber($options['phone_number']); + $vendor->setStatus($options['status']); + $vendor->setEnabled($options['enabled']); + $vendor->setSlug($options['slug']); + $vendor->setDescription($options['description']); + $vendor->setShopUser($user); + $vendor->setVendorAddress($vendorAddress); + $vendor->setSettlementFrequency($options['settlement_frequency']); + + if (null !== $options['image']) { + /** @var string $imagePath */ + $imagePath = $this->fileLocator->locate($options['image']); + $uploadedImage = new UploadedFile($imagePath, basename($imagePath)); + + $vendorImage = $this->vendorImageFactory->create($imagePath, $vendor); + $vendorImage->setFile($uploadedImage); + $this->imageUploader->upload($vendorImage); + $vendor->setImage($vendorImage); + $vendorImage->setOwner($vendor); + } + + if (null !== $options['backgroundImage']) { + /** @var string $imagePath */ + $imagePath = $this->fileLocator->locate($options['backgroundImage']); + $uploadedImage = new UploadedFile($imagePath, basename($imagePath)); + + $vendorbackgroundImage = $this->backgroundImageFactory->create($imagePath, $vendor); + $vendorbackgroundImage->setFile($uploadedImage); + $this->imageUploader->upload($vendorbackgroundImage); + $vendor->setBackgroundImage($vendorbackgroundImage); + $vendorbackgroundImage->setOwner($vendor); + } + if (isset($options['shipping_methods'])) { + $allChannels = $this->channelRepository->findAll(); + + /** @var ChannelInterface $channel */ + foreach ($allChannels as $channel) { + foreach ($options['shipping_methods'] as $shippingMethodCode) { + /** @var ShippingMethodInterface $shippingMethod */ + $shippingMethod = $this->vendorShippingMethodRepository->findOneBy(['code' => $shippingMethodCode]); + $vendorShippingMethod = new VendorShippingMethod(); + $vendorShippingMethod->setVendor($vendor); + $vendorShippingMethod->setShippingMethod($shippingMethod); + $vendorShippingMethod->setChannelCode($channel->getCode()); + + $vendor->addShippingMethod($vendorShippingMethod); + } + } + } + + return $vendor; + } + + protected function configureOptions(OptionsResolver $resolver): void + { + $resolver + ->setDefault('email', fn (Options $options): string => $this->faker->email) + ->setDefault('first_name', fn (Options $options): string => $this->faker->firstName) + ->setDefault('last_name', fn (Options $options): string => $this->faker->lastName) + ->setDefault('password', 'password') + ->setDefault('image', null) + ->setDefault('backgroundImage', null) + ->setDefault('customer_group', LazyOption::randomOneOrNull($this->customerGroupRepository, 100)) + ->setDefault('shipping_methods', fn (Options $options): array => []) + ->setAllowedTypes('customer_group', ['null', 'string', CustomerGroupInterface::class]) + ->setNormalizer('customer_group', LazyOption::findOneBy($this->customerGroupRepository, 'code')) + ->setDefault('gender', CustomerComponent::UNKNOWN_GENDER) + ->setAllowedValues( + 'gender', + [CustomerComponent::UNKNOWN_GENDER, CustomerComponent::MALE_GENDER, CustomerComponent::FEMALE_GENDER], + ) + ->setDefault('birthday', fn (Options $options): \DateTime => $this->faker->dateTimeThisCentury()) + ->setAllowedTypes('birthday', ['null', 'string', \DateTimeInterface::class]) + ->setNormalizer( + 'birthday', + /** @param string|\DateTimeInterface|null $value */ + function (Options $options, string|\DateTimeInterface|null $value) { + if (is_string($value)) { + return \DateTime::createFromFormat('Y-m-d H:i:s', $value); + } + + return $value; + }, + ) + ->setDefault('company_name', fn (Options $options): string => $this->faker->company) + ->setDefault('tax_identifier', fn (Options $options): string => $this->faker->companySuffix) + ->setDefault('bank_account_number', fn (Options $options): string => $this->faker->iban) + ->setDefault('phone_number', fn (Options $options): string => $this->faker->phoneNumber) + ->setDefault('status', VendorInterface::STATUS_VERIFIED) + ->setDefault('enabled', true) + ->setAllowedTypes('enabled', 'bool') + ->setDefault('slug', fn (Options $options): string => StringInflector::nameToCode($options['company_name'])) + ->setDefault('description', fn (Options $options): string => $this->faker->sentence) + ->setDefault('country', LazyOption::randomOne($this->countryRepository)) + ->setAllowedTypes('country', ['null', 'string', CountryInterface::class]) + ->setNormalizer('country', LazyOption::getOneBy($this->countryRepository, 'code')) + ->setDefault('city', fn (Options $options): string => $this->faker->city) + ->setDefault('street', fn (Options $options): string => $this->faker->streetAddress) + ->setDefault('postcode', fn (Options $options): string => $this->faker->postcode) + ->setDefault('settlement_frequency', VendorSettlementFrequency::DEFAULT_SETTLEMENT_FREQUENCY) + ; + } + + private function countryCheck(): void + { + if (0 === count($this->countryRepository->findAll())) { + /** @var CountryInterface $country */ + $country = $this->countryFactory->createNew(); + $country->setCode($this->faker->countryCode); + $country->setEnabled(true); + $this->countryRepository->add($country); + } + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Fixture/OrderFixture.php b/OpenMarketplace/src/Component/Core/Common/Fixture/OrderFixture.php new file mode 100644 index 0000000..7e3a23c --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Fixture/OrderFixture.php @@ -0,0 +1,84 @@ +faker = Factory::create(); + } + + public function load(array $options): void + { + $generateDates = $this->generateDates($options['amount']); + + for ($i = 0; $i < $options['amount']; ++$i) { + $options = array_merge($options, ['complete_date' => array_shift($generateDates)]); + + $orders = $this->orderExampleFactory->createArray($options); + + foreach ($orders as $order) { + $this->orderManager->persist($order); + } + + if (0 === ($i % 50)) { + $this->orderManager->flush(); + } + } + + $this->orderManager->flush(); + } + + public function getName(): string + { + return 'open_marketplace_order'; + } + + protected function configureOptionsNode(ArrayNodeDefinition $optionsNode): void + { + $optionsNode + ->children() + ->integerNode('amount')->isRequired()->min(0)->end() + ->scalarNode('channel')->cannotBeEmpty()->end() + ->scalarNode('customer')->cannotBeEmpty()->end() + ->scalarNode('country')->cannotBeEmpty()->end() + ->booleanNode('fulfilled')->defaultValue(false)->end() + ->end() + ; + } + + private function generateDates(int $amount): array + { + /** @var \DateTimeInterface[] $dates */ + $dates = []; + + for ($i = 0; $i < $amount; ++$i) { + $dates[] = $this->faker->dateTimeBetween('-1 years', 'now'); + } + + sort($dates); + + return $dates; + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Fixture/ProductListingFixture.php b/OpenMarketplace/src/Component/Core/Common/Fixture/ProductListingFixture.php new file mode 100644 index 0000000..78ae478 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Fixture/ProductListingFixture.php @@ -0,0 +1,78 @@ +productDraftExampleFactory->create($productListingData); + $this->productDraftManager->persist($productDraft); + + if (0 === ($i % 50)) { + $this->productDraftManager->flush(); + } + + ++$i; + } + + $this->productDraftManager->flush(); + } + + protected function configureOptionsNode(ArrayNodeDefinition $optionsNode): void + { + $optionsNode + ->children() + ->arrayNode('custom') + ->arrayPrototype() + ->children() + ->scalarNode('vendor')->isRequired()->end() + ->scalarNode('code')->isRequired()->end() + ->scalarNode('name')->isRequired()->end() + ->scalarNode('main_taxon')->isRequired()->end() + ->arrayNode('taxons') + ->scalarPrototype()->end() + ->end() + ->arrayNode('images') + ->scalarPrototype()->end() + ->end() + ->arrayNode('attributes') + ->arrayPrototype() + ->children() + ->scalarNode('code')->end() + ->scalarNode('value')->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ; + } + + public function getName(): string + { + return 'product_listing'; + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Fixture/SettlementFixture.php b/OpenMarketplace/src/Component/Core/Common/Fixture/SettlementFixture.php new file mode 100644 index 0000000..8d1bdff --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Fixture/SettlementFixture.php @@ -0,0 +1,38 @@ +children() + ->scalarNode('vendor')->isRequired()->end() + ->scalarNode('status')->cannotBeEmpty()->end() + ->scalarNode('totalAmount')->cannotBeEmpty()->end() + ->scalarNode('totalCommissionAmount')->cannotBeEmpty()->end() + ->scalarNode('channel')->isRequired()->end() + ->scalarNode('startDate')->end() + ->scalarNode('endDate')->end() + ->end() + ; + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Fixture/VendorFixture.php b/OpenMarketplace/src/Component/Core/Common/Fixture/VendorFixture.php new file mode 100644 index 0000000..1f9cc31 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Fixture/VendorFixture.php @@ -0,0 +1,46 @@ +children() + ->scalarNode('email')->cannotBeEmpty()->end() + ->scalarNode('company_name')->cannotBeEmpty()->end() + ->scalarNode('first_name')->cannotBeEmpty()->end() + ->scalarNode('last_name')->cannotBeEmpty()->end() + ->scalarNode('gender')->end() + ->scalarNode('image')->end() + ->scalarNode('backgroundImage')->end() + ->scalarNode('phone_number')->end() + ->scalarNode('birthday')->end() + ->booleanNode('enabled')->end() + ->scalarNode('password')->cannotBeEmpty()->end() + ->scalarNode('customer_group')->end() + ->scalarNode('settlement_frequency')->end() + ->arrayNode('shipping_methods') + ->scalarPrototype()->end() + ->end() + ; + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Form/Type/Messaging/CategoryType.php b/OpenMarketplace/src/Component/Core/Common/Form/Type/Messaging/CategoryType.php new file mode 100644 index 0000000..2f1a851 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Form/Type/Messaging/CategoryType.php @@ -0,0 +1,42 @@ +add( + 'name', + TextType::class, + [ + 'empty_data' => '', + ] + ); + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefault('data_class', Category::class); + } + + public function getBlockPrefix(): string + { + return 'open_marketplace_messaging_conversation_category'; + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Form/Type/Messaging/ConversationType.php b/OpenMarketplace/src/Component/Core/Common/Form/Type/Messaging/ConversationType.php new file mode 100755 index 0000000..21bb593 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Form/Type/Messaging/ConversationType.php @@ -0,0 +1,104 @@ +add('category', EntityType::class, [ + 'class' => Category::class, + 'required' => false, + 'label' => 'open_marketplace.ui.form.conversation.category', + 'choice_label' => 'name', + ]) + ->add('messages', CollectionType::class, [ + 'entry_type' => MessageType::class, + 'allow_add' => true, + ]) + ->addEventListener(FormEvents::SUBMIT, [$this, 'onSubmit']) + ->addEventListener(FormEvents::POST_SET_DATA, [$this, 'postSetData']); + } + + public function postSetData(FormEvent $event): void + { + $user = $this->currentUserResolver->resolve(); + + if ($user instanceof AdminUserInterface) { + $form = $event->getForm(); + + $form->add('vendorUser', ChoiceType::class, [ + 'choices' => [ + 'Vendors' => $this->vendorRepository->findAll(), + ], + 'choice_label' => 'companyName', + 'mapped' => false, + 'label' => 'open_marketplace.ui.form.conversation.users', + ]); + } + } + + public function onSubmit(FormEvent $event): void + { + /** @var ConversationInterface $conversation */ + $conversation = $event->getData(); + + $resolvedUser = $this->currentUserResolver->resolve(); + + if ($event->getForm()->has('vendorUser') && $resolvedUser instanceof AdminUserInterface) { + if ($event->getForm()->get('vendorUser')->getData()) { + $vendor = $event->getForm()->get('vendorUser')->getData(); + $user = $vendor->getshopUser(); + $conversation->setShopUser($user); + + return; + } + } + + if ($resolvedUser instanceof ShopUser) { + $conversation->setShopUser($resolvedUser); + } + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefault('data_class', Conversation::class); + } + + public function getBlockPrefix(): string + { + return 'mvm_conversation'; + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Form/Type/Messaging/MessageType.php b/OpenMarketplace/src/Component/Core/Common/Form/Type/Messaging/MessageType.php new file mode 100755 index 0000000..a170586 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Form/Type/Messaging/MessageType.php @@ -0,0 +1,52 @@ +add('content', TextareaType::class, [ + 'label' => 'open_marketplace.ui.form.conversation.messages', + 'attr' => [ + 'maxlength' => 500, + ], + 'required' => true, + ]) + ->add('file', FileType::class, [ + 'label' => 'open_marketplace.ui.form.conversation_message.file', + 'required' => false, + ]) + ->add('submit', SubmitType::class, [ + 'label' => 'open_marketplace.ui.form.conversation_message.submit', + ]); + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefault('data_class', Message::class); + } + + public function getBlockPrefix(): string + { + return 'mvm_conversation_message'; + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Form/Type/VendorAddressType.php b/OpenMarketplace/src/Component/Core/Common/Form/Type/VendorAddressType.php new file mode 100644 index 0000000..dad3047 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Form/Type/VendorAddressType.php @@ -0,0 +1,49 @@ +add('country', EntityType::class, [ + 'class' => Country::class, + 'label' => 'open_marketplace.ui.country', + ]) + ->add('city', TextType::class, [ + 'label' => 'open_marketplace.ui.city', + ]) + ->add('street', TextType::class, [ + 'label' => 'open_marketplace.ui.street', + ]) + ->add('postalCode', TextType::class, [ + 'label' => 'open_marketplace.ui.postal_code', + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => Address::class, + ]); + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Resolver/CurrentUserResolver.php b/OpenMarketplace/src/Component/Core/Common/Resolver/CurrentUserResolver.php new file mode 100644 index 0000000..74f31af --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resolver/CurrentUserResolver.php @@ -0,0 +1,33 @@ +tokenStorage->getToken(); + if ($token) { + return $token->getUser(); + } + + return null; + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Resolver/CurrentUserResolverInterface.php b/OpenMarketplace/src/Component/Core/Common/Resolver/CurrentUserResolverInterface.php new file mode 100644 index 0000000..29d4e06 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resolver/CurrentUserResolverInterface.php @@ -0,0 +1,19 @@ + + Click one of the below products to see what you can do with the blocks in your product view! + + section_info_block: + channels: + - "open-marketplace" + sections: + - "products" + translations: + en_US: + content: | +
+ The block you can see on the left is just a block associated with a section named Products +
+

With this feature, you can render any block you want on the product page, like size table, delivery information, or even promotion banner.

+

It's done with a simple controller render:

+
{{ render(path('bitbag_sylius_cms_plugin_shop_block_index_by_section_code', {'sectionCode' : 'products', 'template' : '@BitBagSyliusCmsPlugin/Shop/Block/index.html.twig'})) }}
+ product_info_block: + channels: + - "open-marketplace" + products: 5 + translations: + en_US: + content: | +
On the other hand, the block on the right is a block associated with specific products.
+

This approach can be helpful with displaying some content dedicated to specific products, like size table or product story

+

The way you render it is similar to the one from above example:

+
{{ render(path('bitbag_sylius_cms_plugin_shop_block_index_by_product_code', {'productCode' : product.code, 'template' : '@BitBagSyliusCmsPlugin/Shop/Block/index.html.twig'})) }}
+ homepage_intro: + channels: + - "open-marketplace" + translations: + en_US: + content: | +

Blocks

+

+ The left block is rendered with the usage of the particular controller like this: +

+
+                                            render(path('bitbag_sylius_cms_plugin_shop_block_render', {'code' : 'homepage_header_image'}))
+                                            
+

+ It also can take template as a parameter, but it's optional. In this case, it works the same as below Twig functions. Sometimes you might want the block to render in a different template, that's where the controller is useful. +

+

+ The other three blocks, including this one you are reading right now, are using Twig helper method. +

+ +
+                                            bitbag_cms_render_block('homepage_intro')
+                                            bitbag_cms_render_block('homepage_banner_image_1')
+                                            bitbag_cms_render_block('homepage_banner_image_2')
+                                            
+ lorem_ipsum: + channels: + - "open-marketplace" + sections: + - "homepage" + translations: + en_US: + content: | +

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus

+ +

Pellentesque habitant morbi tristique sene

+ taxons_and_products_block: + channels: + - "open-marketplace" + taxons: + - "clothes" + translations: + en_US: + name: "Clothes" + media: + options: + custom: + homepage_header_image: + type: image + path: "%kernel.project_dir%/vendor/bitbag/cms-plugin/tests/Application/Resources/fixtures/homepage_header.jpeg" + original_name: "homepage_header.jpeg" + channels: + - "open-marketplace" + translations: + en_US: + name: | + This is a linked title + alt: Homepage image media + content: | +

Media description

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +

+ homepage_video: + type: video + path: "%kernel.project_dir%/vendor/bitbag/cms-plugin/tests/Application/Resources/fixtures/homepage_video.mp4" + original_name: "homepage_video.mp4" + channels: + - "open-marketplace" + translations: + en_US: + name: | + Homepage video media + alt: Homepage video + content: | +

Media description

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +

+ homepage_pdf: + type: file + path: "%kernel.project_dir%/vendor/bitbag/cms-plugin/tests/Application/Resources/fixtures/BitBagOffer.pdf" + original_name: "BitBagOffer.pdf" + channels: + - "open-marketplace" + translations: + en_US: + name: Homepage PDF media + alt: BitBag offer + content: | +

File description

+

+ The below button links to a PDF file. + Check it out! +

+ size_table: + channels: + - "open-marketplace" + type: image + path: "%kernel.project_dir%/vendor/bitbag/cms-plugin/tests/Application/Resources/fixtures/size_table.jpeg" + original_name: "size_table.jpeg" + sale: + channels: + - "open-marketplace" + type: image + path: "%kernel.project_dir%/vendor/bitbag/cms-plugin/tests/Application/Resources/fixtures/sale.jpeg" + original_name: "sale.jpeg" + sections: + - "products" + media_with_products: + type: image + path: "%kernel.project_dir%/vendor/bitbag/cms-plugin/tests/Application/Resources/fixtures/homepage_header.jpeg" + original_name: "homepage_header.jpeg" + channels: + - "open-marketplace" + media_with_parameteres: + channels: + - "open-marketplace" + type: image + path: "%kernel.project_dir%/vendor/bitbag/cms-plugin/tests/Application/Resources/fixtures/homepage_header.jpeg" + original_name: "homepage_header.jpeg" + translations: + en_US: + name: Custom media template + content: "This is a custom media template to edit for your needs or create a completely new one." + page: + options: + custom: + lorem_ipsum: + channels: + - "open-marketplace" + number: 14 + products: 5 + sections: + - "blog" + translations: + en_US: + name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Verba tu fingas et ea dicas, quae non sentias?" + name_when_linked: "Lorem ipsum dolor" + description_when_linked: "Lorem ipsum dolor sit amet, consectetur adipiscing elit..." + image_path: "%kernel.project_dir%/vendor/bitbag/cms-plugin/tests/Application/Resources/fixtures/homepage_header.jpeg" + content: | +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Verba tu fingas et ea dicas, quae non sentias? Fortitudinis quaedam praecepta sunt ac paene leges, quae effeminari virum vetant in dolore. Propter nos enim illam, non propter eam nosmet ipsos diligimus. At ego quem huic anteponam non audeo dicere;

+ +

Estne, quaeso, inquam, sitienti in bibendo voluptas? Duo Reges: constructio interrete. Quam si explicavisset, non tam haesitaret. Non enim ipsa genuit hominem, sed accepit a natura inchoatum. Conclusum est enim contra Cyrenaicos satis acute, nihil ad Epicurum. Quis istud, quaeso, nesciebat? Verum tamen cum de rebus grandioribus dicas, ipsae res verba rapiunt;

+ +

Quae cum praeponunt, ut sit aliqua rerum selectio, naturam videntur sequi; Ex quo intellegitur officium medium quiddam esse, quod neque in bonis ponatur neque in contrariis. Quid ergo hoc loco intellegit honestum? Ergo, si semel tristior effectus est, hilara vita amissa est?

+ +

Nam his libris eum malo quam reliquo ornatu villae delectari. Quid est, quod ab ea absolvi et perfici debeat? Ex quo, id quod omnes expetunt, beate vivendi ratio inveniri et comparari potest. Stoici scilicet.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Verba tu fingas et ea dicas, quae non sentias? Fortitudinis quaedam praecepta sunt ac paene leges, quae effeminari virum vetant in dolore. Propter nos enim illam, non propter eam nosmet ipsos diligimus. At ego quem huic anteponam non audeo dicere;

+ +

Estne, quaeso, inquam, sitienti in bibendo voluptas? Duo Reges: constructio interrete. Quam si explicavisset, non tam haesitaret. Non enim ipsa genuit hominem, sed accepit a natura inchoatum. Conclusum est enim contra Cyrenaicos satis acute, nihil ad Epicurum. Quis istud, quaeso, nesciebat? Verum tamen cum de rebus grandioribus dicas, ipsae res verba rapiunt;

+ +

Quae cum praeponunt, ut sit aliqua rerum selectio, naturam videntur sequi; Ex quo intellegitur officium medium quiddam esse, quod neque in bonis ponatur neque in contrariis. Quid ergo hoc loco intellegit honestum? Ergo, si semel tristior effectus est, hilara vita amissa est?

+ +

Nam his libris eum malo quam reliquo ornatu villae delectari. Quid est, quod ab ea absolvi et perfici debeat? Ex quo, id quod omnes expetunt, beate vivendi ratio inveniri et comparari potest. Stoici scilicet.

+ frequently_asked_question: + options: + custom: + lorem_ipsum: + channels: + - "open-marketplace" + number: 10 + translations: + en_US: + question: | + Estne, quaeso, inquam, sitienti in bibendo voluptas? + answer: | + Nam his libris eum malo quam reliquo ornatu villae delectari. Quid est, quod ab ea absolvi et perfici debeat? Ex quo, id quod omnes expetunt, beate vivendi ratio inveniri et comparari potest. Stoici scilicet. diff --git a/OpenMarketplace/src/Component/Core/Common/Resources/fixtures/3_reviews.yaml b/OpenMarketplace/src/Component/Core/Common/Resources/fixtures/3_reviews.yaml new file mode 100644 index 0000000..742b5c6 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resources/fixtures/3_reviews.yaml @@ -0,0 +1,7 @@ +sylius_fixtures: + suites: + open_marketplace: + fixtures: + product_review: + options: + random: 40 diff --git a/OpenMarketplace/src/Component/Core/Common/Resources/resources/messaging.yaml b/OpenMarketplace/src/Component/Core/Common/Resources/resources/messaging.yaml new file mode 100755 index 0000000..d002088 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resources/resources/messaging.yaml @@ -0,0 +1,25 @@ +sylius_resource: + resources: + open_marketplace.conversation: + driver: doctrine/orm + classes: + model: BitBag\OpenMarketplace\Component\Messaging\Entity\Conversation + interface: BitBag\OpenMarketplace\Component\Messaging\Entity\ConversationInterface + controller: Sylius\Bundle\ResourceBundle\Controller\ResourceController + repository: BitBag\OpenMarketplace\Component\Messaging\Repository\ConversationRepository + form: BitBag\OpenMarketplace\Form\Type\Conversation\ConversationType + + open_marketplace.conversation_category: + driver: doctrine/orm + classes: + model: BitBag\OpenMarketplace\Component\Messaging\Entity\Category + interface: BitBag\OpenMarketplace\Component\Messaging\Entity\Conversation\CategoryInterface + repository: BitBag\OpenMarketplace\Component\Messaging\Repository\CategoryRepository + form: BitBag\OpenMarketplace\Component\Core\Common\Form\Type\Messaging\CategoryType + + open_marketplace.conversation_message: + driver: doctrine/orm + classes: + model: BitBag\OpenMarketplace\Component\Messaging\Entity\Message + interface: BitBag\OpenMarketplace\Component\Messaging\Entity\MessageInterface + repository: BitBag\OpenMarketplace\Component\Messaging\Repository\MessageRepository diff --git a/OpenMarketplace/src/Component/Core/Common/Resources/resources/product_listing.yaml b/OpenMarketplace/src/Component/Core/Common/Resources/resources/product_listing.yaml new file mode 100644 index 0000000..f5049f3 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resources/resources/product_listing.yaml @@ -0,0 +1,54 @@ +sylius_resource: + resources: + open_marketplace.product_listing: + driver: doctrine/orm + classes: + model: BitBag\OpenMarketplace\Component\ProductListing\Entity\Listing + repository: BitBag\OpenMarketplace\Component\ProductListing\Repository\ListingRepository + + open_marketplace.product_listing_price: + driver: doctrine/orm + classes: + model: BitBag\OpenMarketplace\Component\ProductListing\Entity\ListingPrice + interface: BitBag\OpenMarketplace\Component\ProductListing\Entity\ListingPriceInterface + + open_marketplace.product_draft: + driver: doctrine/orm + classes: + model: BitBag\OpenMarketplace\Component\ProductListing\Entity\Draft + interface: BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftInterface + controller: Sylius\Bundle\ResourceBundle\Controller\ResourceController + form: BitBag\OpenMarketplace\Component\Core\Vendor\Form\Type\ProductListing\ListingType + + open_marketplace.product_draft_translation: + driver: doctrine/orm + classes: + model: BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftTranslation + interface: BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftTranslationInterface + + open_marketplace.product_draft_image: + driver: doctrine/orm + classes: + model: BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftImage + + open_marketplace.product_draft_taxons: + driver: doctrine/orm + classes: + model: BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftTaxon + interface: BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftTaxonInterface + repository: BitBag\OpenMarketplace\Component\ProductListing\Repository\DraftTaxonRepository + + open_marketplace.product_draft_attribute: + classes: + model: BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttribute + interface: BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttributeInterface + controller: Sylius\Bundle\ResourceBundle\Controller\ResourceController + repository: BitBag\OpenMarketplace\Component\ProductListing\Repository\DraftAttributeRepository + form: BitBag\OpenMarketplace\Component\Core\Vendor\Form\Type\ProductListing\DraftAttributeType + translation: + classes: + model: BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttributeTranslation + + open_marketplace.product_draft_attribute_value: + classes: + model: BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttributeValue diff --git a/OpenMarketplace/src/Component/Core/Common/Resources/resources/settlement.yaml b/OpenMarketplace/src/Component/Core/Common/Resources/resources/settlement.yaml new file mode 100644 index 0000000..288fc0c --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resources/resources/settlement.yaml @@ -0,0 +1,10 @@ +sylius_resource: + resources: + open_marketplace.settlement: + driver: doctrine/orm + classes: + model: BitBag\OpenMarketplace\Component\Settlement\Entity\Settlement + interface: BitBag\OpenMarketplace\Component\Settlement\Entity\SettlementInterface + repository: BitBag\OpenMarketplace\Component\Settlement\Repository\SettlementRepository + factory: BitBag\OpenMarketplace\Component\Settlement\Factory\SettlementFactory + controller: BitBag\OpenMarketplace\Component\Core\Settlement\Controller\SettlementController diff --git a/OpenMarketplace/src/Component/Core/Common/Resources/resources/vendor.yaml b/OpenMarketplace/src/Component/Core/Common/Resources/resources/vendor.yaml new file mode 100755 index 0000000..509b92b --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resources/resources/vendor.yaml @@ -0,0 +1,56 @@ +sylius_resource: + resources: + open_marketplace.vendor: + driver: doctrine/orm + classes: + model: BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor + interface: BitBag\OpenMarketplace\Component\Vendor\Entity\VendorInterface + controller: BitBag\OpenMarketplace\Component\Core\Common\Controller\Resource\VendorController + repository: BitBag\OpenMarketplace\Component\Vendor\Repository\VendorRepository + form: BitBag\OpenMarketplace\Component\Core\Admin\Form\Type\VendorType + + open_marketplace.vendor_profile_update: + classes: + model: BitBag\OpenMarketplace\Component\Vendor\Entity\ProfileUpdate\ProfileUpdate + interface: BitBag\OpenMarketplace\Component\Vendor\Entity\ProfileUpdate\ProfileUpdateInterface + controller: Sylius\Bundle\ResourceBundle\Controller\ResourceController + repository: BitBag\OpenMarketplace\Component\Vendor\Repository\ProfileUpdateRepository + + open_marketplace.vendor_address: + classes: + model: BitBag\OpenMarketplace\Component\Vendor\Entity\Address + interface: BitBag\OpenMarketplace\Component\Vendor\Entity\AddressInterface + controller: Sylius\Bundle\ResourceBundle\Controller\ResourceController + + open_marketplace.vendor_address_update: + classes: + model: BitBag\OpenMarketplace\Component\Vendor\Entity\ProfileUpdate\Address + interface: BitBag\OpenMarketplace\Component\Vendor\Entity\ProfileUpdate\AddressInterface + controller: Sylius\Bundle\ResourceBundle\Controller\ResourceController + + open_marketplace.vendor_shipping_method: + classes: + model: BitBag\OpenMarketplace\Component\Vendor\Entity\VendorShippingMethod + interface: BitBag\OpenMarketplace\Component\Vendor\Entity\VendorShippingMethodInterface + controller: Sylius\Bundle\ResourceBundle\Controller\ResourceController + repository: BitBag\OpenMarketplace\Component\Vendor\Repository\VendorShippingMethodRepository + + open_marketplace.vendor_logo_image: + classes: + model: BitBag\OpenMarketplace\Component\Vendor\Entity\LogoImage + interface: BitBag\OpenMarketplace\Component\Vendor\Entity\LogoImageInterface + form: BitBag\OpenMarketplace\Component\Core\Vendor\Form\Type\Profile\LogoImageType + + open_marketplace.vendor_background_image: + classes: + model: BitBag\OpenMarketplace\Component\Vendor\Entity\BackgroundImage + interface: BitBag\OpenMarketplace\Component\Vendor\Entity\BackgroundImageInterface + form: BitBag\OpenMarketplace\Component\Core\Vendor\Form\Type\Profile\BackgroundImageType + + open_marketplace.vendor_profile_update_logo_image: + classes: + model: BitBag\OpenMarketplace\Component\Vendor\Entity\ProfileUpdate\LogoImage + + open_marketplace.vendor_profile_update_background_image: + classes: + model: BitBag\OpenMarketplace\Component\Vendor\Entity\ProfileUpdate\BackgroundImage diff --git a/OpenMarketplace/src/Component/Core/Common/Resources/resources/virtual_wallet.yaml b/OpenMarketplace/src/Component/Core/Common/Resources/resources/virtual_wallet.yaml new file mode 100644 index 0000000..9d304b0 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resources/resources/virtual_wallet.yaml @@ -0,0 +1,9 @@ +sylius_resource: + resources: + open_marketplace.virtual_wallet: + driver: doctrine/orm + classes: + model: BitBag\OpenMarketplace\Component\Settlement\Entity\VirtualWallet + interface: BitBag\OpenMarketplace\Component\Settlement\Entity\VirtualWalletInterface + repository: BitBag\OpenMarketplace\Component\Settlement\Repository\VirtualWalletRepository + factory: BitBag\OpenMarketplace\Component\Settlement\Factory\VirtualWalletFactory diff --git a/OpenMarketplace/src/Component/Core/Common/Resources/services.xml b/OpenMarketplace/src/Component/Core/Common/Resources/services.xml new file mode 100644 index 0000000..2f79544 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resources/services.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Common/Resources/services/controllers.xml b/OpenMarketplace/src/Component/Core/Common/Resources/services/controllers.xml new file mode 100644 index 0000000..4576802 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resources/services/controllers.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + open_marketplace.settlement + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Common/Resources/services/fixtures/factories.xml b/OpenMarketplace/src/Component/Core/Common/Resources/services/fixtures/factories.xml new file mode 100644 index 0000000..db71297 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resources/services/fixtures/factories.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Common/Resources/services/fixtures/fixtures.xml b/OpenMarketplace/src/Component/Core/Common/Resources/services/fixtures/fixtures.xml new file mode 100644 index 0000000..ad60fc9 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resources/services/fixtures/fixtures.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Common/Resources/services/form_types.xml b/OpenMarketplace/src/Component/Core/Common/Resources/services/form_types.xml new file mode 100644 index 0000000..a34df0f --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resources/services/form_types.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Common/Resources/services/resolvers.xml b/OpenMarketplace/src/Component/Core/Common/Resources/services/resolvers.xml new file mode 100644 index 0000000..6ea8af7 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resources/services/resolvers.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Common/Resources/services/state_machine.xml b/OpenMarketplace/src/Component/Core/Common/Resources/services/state_machine.xml new file mode 100644 index 0000000..96ab715 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resources/services/state_machine.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Common/Resources/services/voters.xml b/OpenMarketplace/src/Component/Core/Common/Resources/services/voters.xml new file mode 100644 index 0000000..c46ec00 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resources/services/voters.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Common/Resources/state_machine/open_marketplace_conversation.yaml b/OpenMarketplace/src/Component/Core/Common/Resources/state_machine/open_marketplace_conversation.yaml new file mode 100755 index 0000000..d8e49e7 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resources/state_machine/open_marketplace_conversation.yaml @@ -0,0 +1,13 @@ +winzou_state_machine: + open_marketplace_conversation: + class: "%open_marketplace.model.conversation.class%" + property_path: status + graph: open_marketplace_conversation + state_machine_class: "%sylius.state_machine.class%" + states: + open: ~ + closed: ~ + transitions: + close: + from: [open] + to: closed diff --git a/OpenMarketplace/src/Component/Core/Common/Resources/state_machine/open_marketplace_draft.yaml b/OpenMarketplace/src/Component/Core/Common/Resources/state_machine/open_marketplace_draft.yaml new file mode 100644 index 0000000..60a0c01 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resources/state_machine/open_marketplace_draft.yaml @@ -0,0 +1,35 @@ +winzou_state_machine: + open_marketplace_draft: + class: '%open_marketplace.model.product_draft.class%' + property_path: status + graph: open_marketplace_draft + state_machine_class: "%sylius.state_machine.class%" + states: + created: ~ + under_verification: ~ + accepted: ~ + rejected: ~ + transitions: + send_to_verification: + from: ['created'] + to: 'under_verification' + accept_product_draft: + from: ['under_verification'] + to: 'accepted' + reject_product_draft: + from: ['under_verification'] + to: 'rejected' + callbacks: + after: + send_to_verification: + on: [ 'send_to_verification' ] + do: [ '@bitbag.open_marketplace.component.core.common.state_machine.product_draft_callbacks', 'sendToVerification' ] + args: [ 'object' ] + accept_product_listing: + on: ['accept_product_draft'] + do: ['@bitbag.open_marketplace.component.core.common.state_machine.product_draft_callbacks', 'accept'] + args: ['object'] + reject_product_listing: + on: [ 'reject_product_draft' ] + do: [ '@bitbag.open_marketplace.component.core.common.state_machine.product_draft_callbacks', 'reject' ] + args: [ 'object' ] diff --git a/OpenMarketplace/src/Component/Core/Common/Resources/state_machine/open_marketplate_settlement.yaml b/OpenMarketplace/src/Component/Core/Common/Resources/state_machine/open_marketplate_settlement.yaml new file mode 100644 index 0000000..41f75ee --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Resources/state_machine/open_marketplate_settlement.yaml @@ -0,0 +1,23 @@ +winzou_state_machine: + open_marketplace_settlement: + class: "%open_marketplace.model.settlement.class%" + property_path: status + graph: open_marketplace_settlement + state_machine_class: "%sylius.state_machine.class%" + states: + new: ~ + accepted: ~ + settled: ~ + transitions: + accept: + from: [new] + to: accepted + settle: + from: [accepted] + to: settled + callbacks: + after: + accept: + on: [ "accept" ] + do: [ "@open_marketplace.component.core.common.state_machine.settlement_callbacks", "payout" ] + args: [ "object" ] diff --git a/OpenMarketplace/src/Component/Core/Common/Security/Voter/ConversationOwningVoter.php b/OpenMarketplace/src/Component/Core/Common/Security/Voter/ConversationOwningVoter.php new file mode 100644 index 0000000..4aedf50 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Security/Voter/ConversationOwningVoter.php @@ -0,0 +1,72 @@ +getUser(); + + if (null === $user || null === $subject) { + return false; + } + + /** @var ConversationInterface $conversation */ + $conversation = $subject; + + switch ($attribute) { + case self::UPDATE: + return $this->doesUserOwnConversation($conversation, $user); + default: + return false; + } + } + + private function doesUserOwnConversation(ConversationInterface $conversation, UserInterface $user): bool + { + $conversationUser = $conversation->getApplicant(); + + if ($user === $conversationUser || + $user instanceof AdminUserInterface) { + return true; + } + + return false; + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/Security/Voter/ObjectOwningVoter.php b/OpenMarketplace/src/Component/Core/Common/Security/Voter/ObjectOwningVoter.php new file mode 100644 index 0000000..e9510e9 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/Security/Voter/ObjectOwningVoter.php @@ -0,0 +1,70 @@ +getUser(); + if (!$user instanceof ShopUserInterface || null == $subject) { + return false; + } + + /** @var ProfileUpdateInterface $vendorUpdateData */ + $vendorUpdateData = $subject; + + switch ($attribute) { + case self::OWNIT: + return $this->doesUserOwnTheData($subject, $user); + default: + return false; + } + } + + private function doesUserOwnTheData(object $data, ShopUserInterface $user): bool + { + $loggedInVendor = $user->getVendor(); + /** @phpstan-ignore-next-line */ + $vendorData = $data->getVendor(); + if ($loggedInVendor === $vendorData) { + return true; + } + + return false; + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/StateMachine/ProductDraftCallbacks.php b/OpenMarketplace/src/Component/Core/Common/StateMachine/ProductDraftCallbacks.php new file mode 100644 index 0000000..8b74a56 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/StateMachine/ProductDraftCallbacks.php @@ -0,0 +1,57 @@ +getProductListing(); + $productListing->sendToVerification($productDraft); + + $this->entityManager->flush(); + + $this->session->add('warning', 'open_marketplace.ui.product_listing_sent_to_verification'); + } + + public function accept(DraftInterface $productDraft): void + { + $product = $this->productDraftService->convertToSimpleProduct($productDraft); + + $this->entityManager->persist($product); + $this->entityManager->flush(); + + $this->session->add('success', 'open_marketplace.ui.product_listing_accepted'); + } + + public function reject(DraftInterface $productDraft): void + { + $productListing = $productDraft->getProductListing(); + $productListing->reject(); + + $this->entityManager->flush(); + + $this->session->add('warning', 'open_marketplace.ui.product_listing_rejected'); + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/StateMachine/ProductDraftStateMachineTransition.php b/OpenMarketplace/src/Component/Core/Common/StateMachine/ProductDraftStateMachineTransition.php new file mode 100644 index 0000000..60b8445 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/StateMachine/ProductDraftStateMachineTransition.php @@ -0,0 +1,40 @@ +productDraftStateMachineFactory->get( + $productDraft, + DraftTransitions::GRAPH + ); + + if (!$stateMachine->can($transition)) { + return; + } + + $stateMachine->apply($transition); + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/StateMachine/ProductDraftStateMachineTransitionInterface.php b/OpenMarketplace/src/Component/Core/Common/StateMachine/ProductDraftStateMachineTransitionInterface.php new file mode 100644 index 0000000..caf86f0 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/StateMachine/ProductDraftStateMachineTransitionInterface.php @@ -0,0 +1,19 @@ +settlementStateMachineTransition->applyIfCan( + $settlement, + SettlementTransitions::SETTLE, + ); + + $this->entityManager->flush(); + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/StateMachine/SettlementCallbacksInterface.php b/OpenMarketplace/src/Component/Core/Common/StateMachine/SettlementCallbacksInterface.php new file mode 100644 index 0000000..6ce73ff --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/StateMachine/SettlementCallbacksInterface.php @@ -0,0 +1,19 @@ +productDraftStateMachineFactory->get( + $settlement, + SettlementTransitions::GRAPH + ); + + if (!$stateMachine->can($transition)) { + return; + } + + $stateMachine->apply($transition); + $this->entityManager->persist($settlement); + } +} diff --git a/OpenMarketplace/src/Component/Core/Common/StateMachine/SettlementStateMachineTransitionInterface.php b/OpenMarketplace/src/Component/Core/Common/StateMachine/SettlementStateMachineTransitionInterface.php new file mode 100644 index 0000000..39b575b --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Common/StateMachine/SettlementStateMachineTransitionInterface.php @@ -0,0 +1,22 @@ +formFactory->create(ProfitWithdrawalType::class); + + $form->handleRequest($request); + + $channelCode = $request->get('channelCode'); + Assert::notNull($channelCode); + + $channel = $this->channelRepository->findOneByCode($channelCode); + Assert::isInstanceOf($channel, ChannelInterface::class); + + if (!$form->isSubmitted() || !$form->isValid()) { + return new Response( + $this->twig->render('Context/Vendor/Settlement/create.html.twig', [ + 'form' => $form->createView(), + 'metadata' => $this->metadata, + 'channel' => $channel, + ]) + ); + } + + $vendor = $this->vendorContext->getVendor(); + Assert::isInstanceOf($vendor, VendorInterface::class); + + $totalAmount = $this->getTotalAmount($form); + + $settlement = $this->settlementCreator->createSettlementForWithdrawal( + $vendor, + $channel, + $totalAmount, + ); + + try { + $this->virtualWalletManager->withdraw($settlement); + } catch (NotEnoughFundsException) { + $this->addFlash('error', 'open_marketplace.ui.not_enough_balance'); + + return new RedirectResponse($this->router->generate('open_marketplace_vendor_virtual_wallet_index')); + } + + $this->entityManager->flush(); + + $this->addFlash('success', 'open_marketplace.ui.settlement_created'); + + return new RedirectResponse($this->router->generate('open_marketplace_vendor_virtual_wallet_index')); + } + + private function addFlash(string $type, string $message): void + { + $session = $this->requestStack->getSession(); + Assert::isInstanceOf($session, SessionInterface::class); + + $flashBag = $session->getBag('flashes'); + Assert::isInstanceOf($flashBag, FlashBagInterface::class); + + $flashBag->add($type, $message); + } + + private function getTotalAmount(FormInterface $form): int + { + $totalAmount = $form->get('totalAmount')->getData(); + Assert::notNull($totalAmount); + + return (int) floor($totalAmount); + } +} diff --git a/OpenMarketplace/src/Component/Core/Settlement/Controller/SettlementController.php b/OpenMarketplace/src/Component/Core/Settlement/Controller/SettlementController.php new file mode 100644 index 0000000..9d1c91e --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Settlement/Controller/SettlementController.php @@ -0,0 +1,37 @@ +requestConfigurationFactory->create($this->metadata, $request); + + $this->isGrantedOr403($configuration, ResourceActions::SHOW); + $resource = $this->findOr404($configuration); + $resources = $this->resourcesCollectionProvider->get($configuration, $this->repository); + + return $this->render($configuration->getTemplate(ResourceActions::SHOW . '.html'), [ + 'configuration' => $configuration, + 'metadata' => $this->metadata, + 'settlement' => $resource, + 'resources' => $resources, + $this->metadata->getName() => $resource, + ]); + } +} diff --git a/OpenMarketplace/src/Component/Core/Settlement/Exception/NotEnoughFundsException.php b/OpenMarketplace/src/Component/Core/Settlement/Exception/NotEnoughFundsException.php new file mode 100644 index 0000000..3ffc2fe --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Settlement/Exception/NotEnoughFundsException.php @@ -0,0 +1,16 @@ +add('totalAmount', MoneyType::class, [ + 'label' => 'open_marketplace.ui.profit_withdrawal_amount', + 'currency' => $options['currency'], + ]) + ->add('save', SubmitType::class, [ + 'label' => 'open_marketplace.ui.withdraw', + 'attr' => [ + 'class' => 'ui primary big button', + ], + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + parent::configureOptions($resolver); + + $request = $this->requestStack->getCurrentRequest(); + Assert::notNull($request); + + $channelCode = $request->get('channelCode'); + Assert::notNull($channelCode); + + $channel = $this->channelRepository->findOneEnabledByCode($channelCode); + Assert::isInstanceOf($channel, ChannelInterface::class); + + $baseCurrency = $channel->getBaseCurrency(); + Assert::isInstanceOf($baseCurrency, CurrencyInterface::class); + + $baseCurrencyCode = $baseCurrency->getCode(); + Assert::notNull($baseCurrencyCode); + + $resolver->setDefault('currency', $baseCurrencyCode); + $resolver->setDefined('currency'); + } + + public function getBlockPrefix(): string + { + return 'bitbag_open_marketplace_profit_withdrawal'; + } +} diff --git a/OpenMarketplace/src/Component/Core/Settlement/Resources/config.yaml b/OpenMarketplace/src/Component/Core/Settlement/Resources/config.yaml new file mode 100644 index 0000000..e834e76 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Settlement/Resources/config.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: 'ui/ui.yaml' } diff --git a/OpenMarketplace/src/Component/Core/Settlement/Resources/services.xml b/OpenMarketplace/src/Component/Core/Settlement/Resources/services.xml new file mode 100644 index 0000000..e1d368b --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Settlement/Resources/services.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Settlement/Resources/services/form.xml b/OpenMarketplace/src/Component/Core/Settlement/Resources/services/form.xml new file mode 100644 index 0000000..a141110 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Settlement/Resources/services/form.xml @@ -0,0 +1,26 @@ + + + + + + + + sylius + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Settlement/Resources/services/twig_extensions.xml b/OpenMarketplace/src/Component/Core/Settlement/Resources/services/twig_extensions.xml new file mode 100644 index 0000000..8217361 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Settlement/Resources/services/twig_extensions.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Settlement/Resources/ui/ui.yaml b/OpenMarketplace/src/Component/Core/Settlement/Resources/ui/ui.yaml new file mode 100644 index 0000000..7b8f966 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Settlement/Resources/ui/ui.yaml @@ -0,0 +1,22 @@ +sylius_ui: + events: + open_marketplace.admin.settlement.show.details: + blocks: + content: + template: 'Configuration/Event/Admin/Settlement/Show/details.html.twig' + priority: 10 + open_marketplace.admin.settlement.show.details_content: + blocks: + table: + template: 'Configuration/Event/Admin/Settlement/Show/detailsTable.html.twig' + priority: 10 + open_marketplace.admin.settlement.show_orders.details: + blocks: + content: + template: 'Configuration/Event/Admin/Settlement/ShowOrders/details.html.twig' + priority: 10 + open_marketplace.admin.settlement.show_orders.details_content: + blocks: + grid: + template: 'Configuration/Event/Admin/Settlement/ShowOrders/grid.html.twig' + priority: 10 diff --git a/OpenMarketplace/src/Component/Core/Settlement/Twig/Extension/SettlementOrderCountExtension.php b/OpenMarketplace/src/Component/Core/Settlement/Twig/Extension/SettlementOrderCountExtension.php new file mode 100644 index 0000000..ab9ea7e --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Settlement/Twig/Extension/SettlementOrderCountExtension.php @@ -0,0 +1,37 @@ +orderRepository->countOrderForSettlement($settlement); + } +} diff --git a/OpenMarketplace/src/Component/Core/Shop/Form/Type/Checkout/SelectShippingType.php b/OpenMarketplace/src/Component/Core/Shop/Form/Type/Checkout/SelectShippingType.php new file mode 100644 index 0000000..c42ec2b --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Shop/Form/Type/Checkout/SelectShippingType.php @@ -0,0 +1,32 @@ +add('shipments', CollectionType::class, [ + 'entry_type' => ShipmentType::class, + 'label' => false, + ]); + } + + public function getBlockPrefix(): string + { + return 'sylius_checkout_select_shipping'; + } +} diff --git a/OpenMarketplace/src/Component/Core/Shop/Form/Type/Checkout/ShipmentType.php b/OpenMarketplace/src/Component/Core/Shop/Form/Type/Checkout/ShipmentType.php new file mode 100644 index 0000000..b620a45 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Shop/Form/Type/Checkout/ShipmentType.php @@ -0,0 +1,56 @@ +addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) { + $form = $event->getForm(); + $shipment = $event->getData(); + $form->add('method', ShippingMethodChoiceType::class, [ + 'required' => true, + 'label' => 'sylius.form.checkout.shipping_method', + 'subject' => $shipment, + 'expanded' => true, + ]); + }) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver + ->setDefaults([ + 'data_class' => $this->dataClass, + ]) + ; + } + + public function getBlockPrefix(): string + { + return 'sylius_checkout_shipment'; + } +} diff --git a/OpenMarketplace/src/Component/Core/Shop/Form/Type/Checkout/ShippingMethodChoiceType.php b/OpenMarketplace/src/Component/Core/Shop/Form/Type/Checkout/ShippingMethodChoiceType.php new file mode 100644 index 0000000..483256f --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Shop/Form/Type/Checkout/ShippingMethodChoiceType.php @@ -0,0 +1,111 @@ +addModelTransformer(new CollectionToArrayTransformer()); + } + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver + ->setDefaults([ + 'choices' => function (Options $options) { + if (isset($options['subject'])) { + return $this->shippingMethodsResolver->getSupportedMethods($options['subject']); + } + + return $this->repository->findAll(); + }, + 'choice_value' => 'code', + 'choice_label' => 'name', + 'choice_translation_domain' => false, + ]) + ->setDefined([ + 'subject', + ]) + ->setAllowedTypes('subject', ShippingSubjectInterface::class) + ; + } + + /** + * @psalm-suppress MissingPropertyType + */ + public function buildView( + FormView $view, + FormInterface $form, + array $options + ): void { + if (!isset($options['subject'])) { + return; + } + + $subject = $options['subject']; + $shippingCosts = []; + + foreach ($view->vars['choices'] as $choiceView) { + $method = $choiceView->data; + + if (!$method instanceof ShippingMethodInterface) { + throw new UnexpectedTypeException($method, ShippingMethodInterface::class); + } + + $methodCalculator = $method->getCalculator(); + + if (null !== $methodCalculator) { + /** @var CalculatorInterface $calculator */ + $calculator = $this->calculators->get($methodCalculator); + $shippingCosts[$choiceView->value] = $calculator->calculate($subject, $method->getConfiguration()); + } + } + + $view->vars['shipping_costs'] = $shippingCosts; + } + + public function getParent(): string + { + return ChoiceType::class; + } + + public function getBlockPrefix(): string + { + return 'sylius_shipping_method_choice'; + } +} diff --git a/OpenMarketplace/src/Component/Core/Shop/Resources/config.yaml b/OpenMarketplace/src/Component/Core/Shop/Resources/config.yaml new file mode 100644 index 0000000..9a9bbf2 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Shop/Resources/config.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: 'grids/*.yaml' } diff --git a/OpenMarketplace/src/Component/Core/Shop/Resources/grids/sylius_shop_account_order.yaml b/OpenMarketplace/src/Component/Core/Shop/Resources/grids/sylius_shop_account_order.yaml new file mode 100644 index 0000000..52a6587 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Shop/Resources/grids/sylius_shop_account_order.yaml @@ -0,0 +1,68 @@ +# This file is part of the Sylius package. +# (c) Paweł Jędrzejewski + +sylius_grid: + grids: + open_marketplace_account_order: + driver: + name: doctrine/orm + options: + class: "%sylius.model.order.class%" + repository: + method: createByCustomerAndChannelIdAndSecondaryQueryBuilder + arguments: + - "expr:service('sylius.context.customer').getCustomer().getId()" + - "expr:service('sylius.context.channel').getChannel().getId()" + sorting: + checkoutCompletedAt: desc + fields: + number: + type: twig + label: sylius.ui.number + sortable: ~ + options: + template: "@SyliusShop/Account/Order/Grid/Field/number.html.twig" + checkoutCompletedAt: + type: datetime + label: sylius.ui.date + sortable: ~ + options: + format: m/d/Y + shippingAddress: + type: twig + label: sylius.ui.ship_to + options: + template: "@SyliusShop/Account/Order/Grid/Field/address.html.twig" + total: + type: twig + label: sylius.ui.total + path: . + sortable: total + options: + template: "@SyliusShop/Account/Order/Grid/Field/total.html.twig" + state: + type: twig + label: sylius.ui.state + sortable: ~ + options: + template: "@SyliusUi/Grid/Field/label.html.twig" + vars: + labels: "@SyliusShop/Account/Order/Label/State" + actions: + item: + show: + type: shop_show + label: sylius.ui.show + options: + link: + route: sylius_shop_account_order_show + parameters: + number: resource.number + pay: + type: shop_pay + label: sylius.ui.pay + options: + link: + route: sylius_shop_order_show + parameters: + tokenValue: resource.primaryOrder.tokenValue diff --git a/OpenMarketplace/src/Component/Core/Shop/Resources/grids/sylius_shop_vendor_product.yaml b/OpenMarketplace/src/Component/Core/Shop/Resources/grids/sylius_shop_vendor_product.yaml new file mode 100644 index 0000000..ee62ca4 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Shop/Resources/grids/sylius_shop_vendor_product.yaml @@ -0,0 +1,40 @@ +sylius_grid: + grids: + open_marketplace_vendor_shop_product: + driver: + name: doctrine/orm + options: + class: "%sylius.model.product.class%" + repository: + method: createVendorShopListQueryBuilder + arguments: + vendor: "expr:notFoundOnNull(service('bitbag.open_marketplace.component.vendor.repository.vendor').findOneBySlug($vendor_slug))" + channel: "expr:service('sylius.context.channel').getChannel()" + taxon: "expr:notFoundOnNull(service('bitbag.open_marketplace.component.vendor.context.taxon').getForVendorPage(service('request_stack').getCurrentRequest().attributes.get('slug', null), service('sylius.context.locale').getLocaleCode()))" + locale: "expr:service('sylius.context.locale').getLocaleCode()" + sorting: "expr:service('request_stack').getCurrentRequest().get('sorting', [])" + includeAllDescendants: "expr:parameter('sylius_shop.product_grid.include_all_descendants')" + sorting: + position: asc + limits: [9, 18, 27] + fields: + createdAt: + type: datetime + sortable: ~ + position: + type: string + sortable: productTaxon.position + name: + type: string + sortable: translation.name + price: + type: int + sortable: channelPricing.price + filters: + search: + type: shop_string + label: false + options: + fields: [translation.name] + form_options: + type: contains diff --git a/OpenMarketplace/src/Component/Core/Shop/Resources/routing.yaml b/OpenMarketplace/src/Component/Core/Shop/Resources/routing.yaml new file mode 100644 index 0000000..0191a66 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Shop/Resources/routing.yaml @@ -0,0 +1,5 @@ +open_marketplace_shop_vendor_page: + resource: "routing/vendor_page.yaml" + prefix: /{_locale}/vendors + requirements: + _locale: ^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$ diff --git a/OpenMarketplace/src/Component/Core/Shop/Resources/routing/vendor_page.yaml b/OpenMarketplace/src/Component/Core/Shop/Resources/routing/vendor_page.yaml new file mode 100644 index 0000000..28acde8 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Shop/Resources/routing/vendor_page.yaml @@ -0,0 +1,34 @@ +open_marketplace_shop_vendor_page_index: + path: /{vendor_slug} + methods: [GET] + defaults: + _controller: sylius.controller.product:indexAction + _sylius: + template: "Context/Vendor/VendorPage/index.html.twig" + grid: open_marketplace_vendor_shop_product + +open_marketplace_shop_vendor_page_product_index: + path: /{vendor_slug}/taxons/{slug} + methods: [GET] + requirements: + slug: .+(? + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Shop/Resources/services/form_types.xml b/OpenMarketplace/src/Component/Core/Shop/Resources/services/form_types.xml new file mode 100644 index 0000000..4c215a5 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Shop/Resources/services/form_types.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + %sylius.model.order.class% + %sylius.form.type.checkout_select_shipping.validation_groups% + + + + + %sylius.model.shipment.class% + %sylius.form.type.checkout_shipment.validation_groups% + + + + diff --git a/OpenMarketplace/src/Component/Core/Shop/Resources/validation/ChannelPricing.xml b/OpenMarketplace/src/Component/Core/Shop/Resources/validation/ChannelPricing.xml new file mode 100644 index 0000000..ad42b5d --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Shop/Resources/validation/ChannelPricing.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Vendor/Controller/Messaging/ListThreadsAction.php b/OpenMarketplace/src/Component/Core/Vendor/Controller/Messaging/ListThreadsAction.php new file mode 100644 index 0000000..b5a689f --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Controller/Messaging/ListThreadsAction.php @@ -0,0 +1,60 @@ +attributes->get('_sylius')['template']; + + /** @var ShopUserInterface $currentUser */ + $currentUser = $this->currentUserResolver->resolve(); + + $status = Conversation::STATUS_OPEN; + + if ($request->query->get('closed')) { + $status = Conversation::STATUS_CLOSED; + } + + $conversations = $this->conversationRepository->findAllWithStatusAndUser($status, $currentUser); + + /** @var VendorInterface $vendor */ + $vendor = $currentUser->getVendor(); + + return new Response( + $this->templatingEngine->render( + $template, + [ + 'conversations' => $conversations, + 'account_disabled' => false === $vendor->isEnabled(), + ] + ) + ); + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Controller/Order/ResendConfirmationEmailAction.php b/OpenMarketplace/src/Component/Core/Vendor/Controller/Order/ResendConfirmationEmailAction.php new file mode 100644 index 0000000..eac3575 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Controller/Order/ResendConfirmationEmailAction.php @@ -0,0 +1,63 @@ +attributes->get('id'); + + if (!$this->csrfTokenManager->isTokenValid(new CsrfToken($orderId, (string) $request->query->get('_csrf_token')))) { + throw new HttpException(Response::HTTP_FORBIDDEN, $this->translator->trans('open_marketplace.ui.invalid_csrf')); + } + + /** @var OrderInterface|null $order */ + $order = $this->orderRepository->find($orderId); + if (null === $order) { + throw new NotFoundHttpException($this->translator->trans('open_marketplace.ui.order_not_found', ['orderId' => $orderId])); + } + + $this->orderEmailManager->sendConfirmationEmail($order); + + $this->session->getFlashBag()->add( + 'success', + 'sylius.email.order_confirmation_resent', + ); + + return new RedirectResponse($this->router->generate('open_marketplace_vendor_orders_listing')); + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Controller/ProductListing/CreateAction.php b/OpenMarketplace/src/Component/Core/Vendor/Controller/ProductListing/CreateAction.php new file mode 100644 index 0000000..015f92b --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Controller/ProductListing/CreateAction.php @@ -0,0 +1,93 @@ +tokenStorage->getToken(); + + /** @var ShopUserInterface $user */ + $user = $token->getUser(); + + $vendor = $user->getVendor(); + Assert::isInstanceOf($vendor, VendorInterface::class); + + $configuration = $this->requestConfigurationFactory->create($this->metadata, $request); + + /** @var DraftInterface $productDraft */ + $productDraft = $this->newResourceFactory->create($configuration, $this->factory); + + $form = $this->formFactory->create(ListingType::class, $productDraft); + $form->handleRequest($request); + + if ($request->isMethod('POST') && $form->isSubmitted() && $form->isValid()) { + $this->listingPersister->createNewProductListing($productDraft, $vendor); + $this->productDraftRepository->save($productDraft); + + /** @var Session $session */ + $session = $this->requestStack->getSession(); + $session->getFlashBag()->add('success', 'open_marketplace.ui.product_listing_created'); + + return new RedirectResponse($this->router->generate('open_marketplace_vendor_product_listings_index')); + } + + return new Response( + $this->twig->render('Context/Vendor/ProductListing/create.html.twig', [ + 'configuration' => $configuration, + 'metadata' => $this->metadata, + 'resource' => $productDraft, + $this->metadata->getName() => $productDraft, + 'form' => $form->createView(), + ]) + ); + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Controller/ProductListing/EnableAction.php b/OpenMarketplace/src/Component/Core/Vendor/Controller/ProductListing/EnableAction.php new file mode 100644 index 0000000..0b93edc --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Controller/ProductListing/EnableAction.php @@ -0,0 +1,53 @@ +productListingRepository->find($request->get('id')); + + $enableState = $listing->isEnabled(); + + $listing->setEnabled(!$enableState); + $product = $listing->getProduct(); + + if ($product) { + $product->setEnabled($enableState); + $this->entityManager->persist($product); + } + + $msgString = $enableState ? 'open_marketplace.ui.enabled' : 'open_marketplace.ui.disabled'; + + $this->flashBag->set('success', $msgString); + $this->entityManager->persist($listing); + $this->entityManager->flush(); + + return new RedirectResponse($this->router->generate('open_marketplace_vendor_product_listings_index')); + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Controller/ProductListing/RemoveAction.php b/OpenMarketplace/src/Component/Core/Vendor/Controller/ProductListing/RemoveAction.php new file mode 100644 index 0000000..0aaf5a4 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Controller/ProductListing/RemoveAction.php @@ -0,0 +1,52 @@ +productListingRepository->find($request->attributes->get('id')); + + $productListing->remove(); + + $product = $productListing->getProduct(); + + if ($product) { + $product->setEnabled(false); + $this->entityManager->persist($product); + } + + $this->entityManager->persist($productListing); + $this->entityManager->flush(); + $this->flashBag->set('success', 'open_marketplace.ui.removed'); + + return new RedirectResponse($this->router->generate('open_marketplace_vendor_product_listings_index')); + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Controller/ProductListing/SendForVerificationAction.php b/OpenMarketplace/src/Component/Core/Vendor/Controller/ProductListing/SendForVerificationAction.php new file mode 100644 index 0000000..fee2307 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Controller/ProductListing/SendForVerificationAction.php @@ -0,0 +1,46 @@ +productListingRepository->find($request->get('id')); + + /** @var DraftInterface $productDraft */ + $productDraft = $this->productDraftRepository->findLatestDraft($listing); + + if (null != $productDraft && DraftInterface::STATUS_CREATED === $productDraft->getStatus()) { + $this->productDraftStateMachineTransition->applyIfCan($productDraft, DraftTransitions::TRANSITION_SEND_TO_VERIFICATION); + } + + return new RedirectResponse($this->router->generate('open_marketplace_vendor_product_listings_index')); + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Controller/ProductListing/UpdateAction.php b/OpenMarketplace/src/Component/Core/Vendor/Controller/ProductListing/UpdateAction.php new file mode 100644 index 0000000..77f4708 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Controller/ProductListing/UpdateAction.php @@ -0,0 +1,96 @@ +requestConfigurationFactory->create($this->metadata, $request); + + /** @var ListingInterface $productListing */ + $productListing = $this->productListingRepository->find($request->get('id')); + + if (!$this->authorizationChecker->isGranted(ObjectOwningVoter::OWNIT, $productListing)) { + throw new AccessDeniedException(); + } + + if ($productListing->isRemoved()) { + /** @var Session $session */ + $session = $this->requestStack->getSession(); + $session->getFlashBag()->add('error', 'open_marketplace.ui.product_listing_removed'); + + return new RedirectResponse($this->router->generate('open_marketplace_vendor_product_listings_index')); + } + + $productDraft = $this->listingPersister->resolveLatestDraft($productListing); + + $form = $this->formFactory->create(ListingType::class, $productDraft); + $form->handleRequest($request); + + if ($request->isMethod('POST') && $form->isSubmitted() && $form->isValid()) { + $productDraft->ownRelations(); + $this->listingPersister->uploadImages($productDraft); + + $this->productDraftRepository->save($productDraft); + + /** @var Session $session */ + $session = $this->requestStack->getSession(); + $session->getFlashBag()->add('success', 'open_marketplace.ui.product_listing_saved'); + + return new RedirectResponse($this->router->generate('open_marketplace_vendor_product_listings_index')); + } + + return new Response( + $this->twig->render('Context/Vendor/ProductListing/update.html.twig', [ + 'configuration' => $configuration, + 'metadata' => $this->metadata, + 'resource' => $productDraft, + $this->metadata->getName() => $productDraft, + 'form' => $form->createView(), + ]) + ); + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Controller/Profile/ConfirmUpdateAction.php b/OpenMarketplace/src/Component/Core/Vendor/Controller/Profile/ConfirmUpdateAction.php new file mode 100644 index 0000000..54feaf8 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Controller/Profile/ConfirmUpdateAction.php @@ -0,0 +1,51 @@ +entityManager->getRepository(ProfileUpdate::class)->findOneBy(['token' => $token]); + $profileRoot = $this->router->generate('open_marketplace_vendor_profile_details'); + $vendorIsGranted = $this->security->isGranted(TokenOwningVoter::UPDATE, $vendorProfileUpdateData); + if ($vendorIsGranted && null !== $vendorProfileUpdateData) { + $this->vendorProfileUpdateService->updateVendorFromPendingData($vendorProfileUpdateData); + + $loggedVendor = $this->vendorProvider->getVendor(); + $loggedVendor->setEditedAt(null); + + $this->entityManager->flush(); + } + + return new RedirectResponse($profileRoot); + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/EventListener/RegisterListener.php b/OpenMarketplace/src/Component/Core/Vendor/EventListener/RegisterListener.php new file mode 100644 index 0000000..b28ff26 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/EventListener/RegisterListener.php @@ -0,0 +1,92 @@ +getSubject(); + + /** @var LogoImageInterface $vendorImage */ + $vendorImage = $vendor->getImage(); + + if (null !== $vendorImage) { + $this->fileUploader->upload($vendorImage); + + $vendorImage->setOwner($vendor); + } + } + + public function uploadBackgroundImage(ResourceControllerEvent $event): void + { + /** @var VendorInterface $vendor */ + $vendor = $event->getSubject(); + + /** @var BackgroundImageInterface $vendorBackgroundImage */ + $vendorBackgroundImage = $vendor->getBackgroundImage(); + + if (null !== $vendorBackgroundImage) { + $this->fileUploader->upload($vendorBackgroundImage); + + $vendorBackgroundImage->setOwner($vendor); + } + } + + public function generateSlug(ResourceControllerEvent $event): void + { + /** @var VendorInterface $vendor */ + $vendor = $event->getSubject(); + + if (null === $vendor->getCompanyName()) { + throw new \Exception('Company name cannot be empty.'); + } + + $vendor->setSlug($this->vendorSlugGenerator->generateSlug($vendor->getCompanyName())); + } + + public function connectShopUser(ResourceControllerEvent $event): void + { + /** @var VendorInterface $vendor */ + $vendor = $event->getSubject(); + $token = $this->tokenStorage->getToken(); + if (null === $token) { + throw new TokenNotFoundException(); + } + + /** @var ShopUserInterface|null $shopUser */ + $shopUser = $token->getUser(); + if (null === $shopUser) { + throw new ShopUserNotFoundException(); + } + $vendor->setShopUser($shopUser); + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/EventListener/VendorListener.php b/OpenMarketplace/src/Component/Core/Vendor/EventListener/VendorListener.php new file mode 100644 index 0000000..1dec6c3 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/EventListener/VendorListener.php @@ -0,0 +1,56 @@ +getObjectManager(); + $unitOfWork = $objectManager->getUnitOfWork(); + $changeSet = $unitOfWork->getEntityChangeSet($vendor); + + if (!array_key_exists(self::SETTLEMENT_FREQUENCY, $changeSet)) { + return; + } + + $frequencyChangeSet = $changeSet[self::SETTLEMENT_FREQUENCY]; + + $previousFrequency = $frequencyChangeSet[0]; + if (!in_array($previousFrequency, VendorSettlementFrequency::SETTLEMENT_FREQUENCIES, true)) { + throw new \RuntimeException(sprintf( + 'Invalid settlement frequency "%s", unable to create compensatory settlement for vendor %s with id %d', + $previousFrequency, + $vendor->getSlug(), + $vendor->getId() + )); + } + + $this->compensatorySettlementsCreator->createCompensatorySettlements($vendor, $eventArgs, $previousFrequency); + + $this->entityManager->flush(); + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/EventSubscriber/AccessDeniedSubscriber.php b/OpenMarketplace/src/Component/Core/Vendor/EventSubscriber/AccessDeniedSubscriber.php new file mode 100644 index 0000000..9f22105 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/EventSubscriber/AccessDeniedSubscriber.php @@ -0,0 +1,76 @@ + ['onKernelException', 2], + ]; + } + + public function onKernelException(ExceptionEvent $event): void + { + $exception = $event->getThrowable(); + if (!$exception instanceof AccessDeniedHttpException) { + return; + } + + /** @var Request $currentRequest */ + $currentRequest = $this->requestStack->getCurrentRequest(); + + $uriParts = explode('/', $currentRequest->getRequestUri()); + if ('' === $uriParts[0]) { + array_shift($uriParts); + } + + if (4 > count($uriParts)) { + return; + } + + if ('account' !== $uriParts[1] || 'vendor' !== $uriParts[2] || 'conversations' === $uriParts[3]) { + return; + } + + try { + $currentVendor = $this->vendorProvider->getVendor(); + if (false === $currentVendor->isEnabled()) { + $event->setResponse(new RedirectResponse( + $this->router->generate('open_marketplace_vendor_messaging_conversation_index') + )); + $event->stopPropagation(); + } + } catch (ShopUserHasNoVendorContextException|ShopUserNotFoundException $e) { + } + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Exception/ShopUserHasNoVendorContextException.php b/OpenMarketplace/src/Component/Core/Vendor/Exception/ShopUserHasNoVendorContextException.php new file mode 100644 index 0000000..40d52c1 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Exception/ShopUserHasNoVendorContextException.php @@ -0,0 +1,16 @@ +productDraftTaxonFactory = $productDraftTaxonFactory; + $this->productDraftTaxonRepository = $productDraftTaxonRepository; + $this->productDraft = $productDraft; + } + + public function transform(mixed $value): ?TaxonInterface + { + if (null === $value) { + return null; + } + + $this->assertTransformationValueType($value, DraftTaxonInterface::class); + + return $value->getTaxon(); + } + + public function reverseTransform($value): ?DraftTaxonInterface + { + if (null === $value) { + return null; + } + + $this->assertTransformationValueType($value, TaxonInterface::class); + + /** @var DraftTaxonInterface|null $productDraftTaxon */ + $productDraftTaxon = $this->productDraftTaxonRepository->findOneBy(['taxon' => $value, 'productDraft' => $this->productDraft]); + + if (null === $productDraftTaxon) { + /** @var DraftTaxonInterface $productDraftTaxon */ + $productDraftTaxon = $this->productDraftTaxonFactory->createNew(); + $productDraftTaxon->setProductDraft($this->productDraft); + $productDraftTaxon->setTaxon($value); + } + + return $productDraftTaxon; + } + + /** + * @throws TransformationFailedException + */ + private function assertTransformationValueType(mixed $value, string $expectedType): void + { + if (!($value instanceof $expectedType)) { + throw new TransformationFailedException( + sprintf( + 'Expected "%s", but got "%s"', + $expectedType, + get_debug_type($value), + ), + ); + } + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftAttributeChoiceType.php b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftAttributeChoiceType.php new file mode 100644 index 0000000..c06651e --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftAttributeChoiceType.php @@ -0,0 +1,48 @@ +attributeRepository = $attributeRepository; + $this->vendorProvider = $vendorProvider; + } + + public function configureOptions(OptionsResolver $resolver): void + { + /** @var DraftAttributeRepositoryInterface $draftAttributeRepository */ + $draftAttributeRepository = $this->attributeRepository; + $resolver + ->setDefaults([ + 'choices' => [$draftAttributeRepository->findVendorDraftAttributes($this->vendorProvider->getVendor())], + 'choice_value' => 'code', + 'choice_label' => 'name', + 'choice_translation_domain' => false, + 'required' => false, + ]); + } + + public function getBlockPrefix(): string + { + return 'sylius_product_attribute_choice'; + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftAttributeTranslationType.php b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftAttributeTranslationType.php new file mode 100644 index 0000000..f4f70cc --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftAttributeTranslationType.php @@ -0,0 +1,22 @@ +add('position', IntegerType::class, [ + 'required' => false, + 'label' => 'sylius.form.product_attribute.position', + 'invalid_message' => 'sylius.product_attribute.invalid', + ]) + ; + } + + public function getBlockPrefix(): string + { + return 'sylius_product_attribute'; + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftAttributeValueType.php b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftAttributeValueType.php new file mode 100644 index 0000000..c5cc1a4 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftAttributeValueType.php @@ -0,0 +1,22 @@ +vars['product'] = $options['product']; + } + + public function configureOptions(OptionsResolver $resolver): void + { + parent::configureOptions($resolver); + + $resolver->setDefined('product'); + $resolver->setAllowedTypes('product', DraftInterface::class); + } + + public function getBlockPrefix(): string + { + return 'sylius_product_image'; + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftPriceType.php b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftPriceType.php new file mode 100755 index 0000000..22fea8f --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftPriceType.php @@ -0,0 +1,105 @@ +channelPricingRepository = $channelPricingRepository; + parent::__construct($dataClass, $validationGroups); + } + + public function buildForm(FormBuilderInterface $builder, array $options): void + { + $builder + ->add('price', MoneyType::class, [ + 'label' => 'sylius.ui.price', + 'currency' => $options['channel']->getBaseCurrency()->getCode(), + ]) + ->add('originalPrice', MoneyType::class, [ + 'label' => 'sylius.ui.original_price', + 'required' => false, + 'currency' => $options['channel']->getBaseCurrency()->getCode(), + ]) + ->add('minimumPrice', MoneyType::class, [ + 'label' => 'sylius.ui.minimum_price', + 'required' => false, + 'currency' => $options['channel']->getBaseCurrency()->getCode(), + 'empty_data' => '0.00', + ]) + ; + + $builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) use ($options): void { + $pricing = $event->getData(); + + if (!$pricing instanceof $this->dataClass || !$pricing instanceof ListingPriceInterface) { + $event->setData(null); + + return; + } + + if ((null === $pricing->getPrice()) && (null === $pricing->getOriginalPrice())) { + $event->setData(null); + + if (null !== $pricing->getId()) { + $this->channelPricingRepository->remove($pricing); + } + + return; + } + + $pricing->setChannelCode($options['channel']->getCode()); + $pricing->setProductDraft($options['product_draft']); + + $event->setData($pricing); + }); + } + + public function getBlockPrefix(): string + { + return 'bitbag_product_product'; + } + + public function configureOptions(OptionsResolver $resolver): void + { + parent::configureOptions($resolver); + + $resolver + ->setRequired('channel') + ->setAllowedTypes('channel', [ChannelInterface::class]) + ->setDefined('product_draft') + ->setAllowedTypes('product_draft', ['null', DraftInterface::class]) + + ->setDefaults([ + 'label' => fn (Options $options): string => $options['channel']->getName(), + ]) + ; + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftTaxonAutocompleteChoiceType.php b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftTaxonAutocompleteChoiceType.php new file mode 100644 index 0000000..67fd285 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftTaxonAutocompleteChoiceType.php @@ -0,0 +1,82 @@ +productDraftTaxonFactory = $productDraftTaxonFactory; + $this->productDraftTaxonRepository = $productDraftTaxonRepository; + } + + public function buildForm(FormBuilderInterface $builder, array $options): void + { + if ($options['multiple']) { + $builder->addModelTransformer( + new RecursiveTransformer( + new ProductDraftTaxonToTaxonTransformer( + $this->productDraftTaxonFactory, + $this->productDraftTaxonRepository, + $options['productDraft'], + ), + ), + ); + } else { + $builder->addModelTransformer( + new ProductDraftTaxonToTaxonTransformer( + $this->productDraftTaxonFactory, + $this->productDraftTaxonRepository, + $options['productDraft'], + ), + ); + } + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'resource' => 'sylius.taxon', + 'choice_name' => 'name', + 'choice_value' => 'code', + ]); + + $resolver + ->setRequired('productDraft') + ->setAllowedTypes('productDraft', DraftInterface::class) + ; + } + + public function getParent(): string + { + return ResourceAutocompleteChoiceType::class; + } + + public function getBlockPrefix(): string + { + return 'sylius_product_taxon_autocomplete_choice'; + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftTranslationType.php b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftTranslationType.php new file mode 100644 index 0000000..9ae803c --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftTranslationType.php @@ -0,0 +1,59 @@ +add('name', TextType::class, [ + 'label' => 'sylius.form.product.name', + ]) + ->add('slug', TextType::class, [ + 'label' => 'sylius.form.product.slug', + ]) + ->add('description', TextareaType::class, [ + 'required' => false, + 'label' => 'sylius.form.product.description', + ]) + ->add('metaKeywords', TextType::class, [ + 'required' => false, + 'label' => 'sylius.form.product.meta_keywords', + ]) + ->add('metaDescription', TextType::class, [ + 'required' => false, + 'label' => 'sylius.form.product.meta_description', + ]) + ->add('shortDescription', TextareaType::class, [ + 'required' => false, + 'label' => 'sylius.form.product.short_description', + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => $this->dataClass, + ]); + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftTranslationsCollectionType.php b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftTranslationsCollectionType.php new file mode 100644 index 0000000..85f1632 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/DraftTranslationsCollectionType.php @@ -0,0 +1,86 @@ +definedLocalesCodes = $localeProvider->getDefinedLocalesCodes(); + $this->defaultLocaleCode = $localeProvider->getDefaultLocaleCode(); + } + + public function buildForm(FormBuilderInterface $builder, array $options): void + { + $builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) { + /** @var DraftTranslationInterface[]|null[] $translations */ + $translations = $event->getData(); + + $parentForm = $event->getForm()->getParent(); + Assert::notNull($parentForm); + + /** @var DraftTranslationInterface $translation */ + foreach ($translations as $localeCode => $translation) { + if (null == $translation) { + throw new TranslationNotFoundException('Translation not found.'); + } + + if (null === $translation->getName()) { + unset($translations[$localeCode]); + + continue; + } + + $translation->setLocale($localeCode); + } + + $event->setData($translations); + }); + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'entries' => $this->definedLocalesCodes, + 'entry_name' => function (string $localeCode): string { + return $localeCode; + }, + 'entry_options' => function (string $localeCode): array { + return [ + 'required' => $localeCode === $this->defaultLocaleCode, + ]; + }, + ]); + } + + public function getParent(): string + { + return FixedCollectionType::class; + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/ListingType.php b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/ListingType.php new file mode 100755 index 0000000..da49498 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductListing/ListingType.php @@ -0,0 +1,131 @@ +add('code', TextType::class, [ + 'label' => 'sylius.ui.code', + 'disabled' => ($builder->getData()->getCode()), + ]) + ->add('shippingRequired', CheckboxType::class, [ + 'label' => 'sylius.form.variant.shipping_required', + 'required' => false, + ]) + ->add('shippingCategory', ShippingCategoryChoiceType::class, [ + 'required' => false, + 'placeholder' => 'sylius.ui.no_requirement', + 'label' => 'sylius.form.product_variant.shipping_category', + ]) + ->add('translations', DraftTranslationsCollectionType::class, [ + 'entry_type' => DraftTranslationType::class, + 'label' => 'sylius.form.product.translations', + 'attr' => [ + 'class' => 'ui styled fluid accordion', + ], + 'constraints' => [new Valid(['groups' => 'sylius'])], + ]) + ->add('save', SubmitType::class, [ + 'label' => 'open_marketplace.ui.save_draft', + 'attr' => [ + 'class' => 'ui primary big button', + ], + ]) + ->add('attributes', CollectionType::class, [ + 'entry_type' => DraftAttributeValueType::class, + 'required' => false, + 'prototype' => true, + 'allow_add' => true, + 'allow_delete' => true, + 'by_reference' => true, + 'label' => false, + ]) + ->add('channels', ChannelChoiceType::class, [ + 'multiple' => true, + 'expanded' => true, + 'label' => 'sylius.form.product.channels', + ]) + ->add('mainTaxon', TaxonAutocompleteChoiceType::class, [ + 'label' => 'sylius.form.product.main_taxon', + 'required' => false, + ]) + ->add('taxCategory', TaxCategoryChoiceType::class, [ + 'required' => false, + 'placeholder' => '---', + 'label' => 'sylius.form.product_variant.tax_category', + ]) + ->add('images', CollectionType::class, [ + 'entry_type' => DraftImageType::class, + 'entry_options' => ['product' => $options['data']], + 'allow_add' => true, + 'allow_delete' => true, + 'by_reference' => true, + 'required' => false, + 'label' => 'sylius.form.product.images', + 'block_name' => 'entry', + ]); + + $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event): void { + $productDraft = $event->getData(); + + $event->getForm() + ->add('productListingPrices', ChannelCollectionType::class, [ + 'entry_type' => DraftPriceType::class, + 'entry_options' => fn (ChannelInterface $channel) => [ + 'channel' => $channel, + 'product_draft' => $productDraft, + 'required' => false, + ], + 'label' => 'sylius.form.variant.price', + ]) + ->add('productDraftTaxons', DraftTaxonAutocompleteChoiceType::class, [ + 'label' => 'sylius.form.product.taxons', + 'productDraft' => $productDraft, + 'multiple' => true, + 'required' => false, + ]); + }); + } + + public function getBlockPrefix(): string + { + return 'sylius_product'; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'compound' => true, + 'validation_groups' => 'sylius', + ]); + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductReviewType.php b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductReviewType.php new file mode 100644 index 0000000..9c8c949 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/ProductReviewType.php @@ -0,0 +1,31 @@ +add('title', TextType::class, [ + 'label' => 'sylius.form.review.title', + ]) + ->add('comment', TextareaType::class, [ + 'label' => 'sylius.form.review.comment', + ]) + ; + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Form/Type/Profile/BackgroundImageType.php b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/Profile/BackgroundImageType.php new file mode 100644 index 0000000..ea34aa4 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/Profile/BackgroundImageType.php @@ -0,0 +1,33 @@ +add('file', FileType::class, [ + 'label' => 'open_marketplace.ui.background', + ]) + ; + } + + public function getBlockPrefix(): string + { + return 'sylius_avatar_image'; + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Form/Type/Profile/LogoImageType.php b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/Profile/LogoImageType.php new file mode 100644 index 0000000..b872387 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/Profile/LogoImageType.php @@ -0,0 +1,33 @@ +add('file', FileType::class, [ + 'label' => 'open_marketplace.ui.logo', + ]) + ; + } + + public function getBlockPrefix(): string + { + return 'sylius_avatar_image'; + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Form/Type/Profile/ProfileType.php b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/Profile/ProfileType.php new file mode 100644 index 0000000..1317b6d --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/Profile/ProfileType.php @@ -0,0 +1,74 @@ +add('companyName', TextType::class, [ + 'label' => 'open_marketplace.ui.company_name', + ]) + ->add('taxIdentifier', TextType::class, [ + 'label' => 'open_marketplace.ui.tax_identifier', + ]) + ->add('bankAccountNumber', TextType::class, [ + 'label' => 'open_marketplace.ui.bank_account_number', + ]) + ->add('phoneNumber', TelType::class, [ + 'label' => 'open_marketplace.ui.phone_number', + ]) + ->add('image', LogoImageType::class, [ + 'label' => false, + 'required' => false, + 'constraints' => [new Valid(['groups' => 'VendorLogo'])], + ]) + ->add('backgroundImage', BackgroundImageType::class, [ + 'label' => false, + 'required' => false, + 'constraints' => [new Valid(['groups' => 'VendorBackground'])], + ]) + ->add('vendorAddress', VendorAddressType::class, [ + 'label' => 'open_marketplace.ui.company_address', + 'constraints' => [new Valid()], + ]) + ->add('description', TextType::class, [ + 'label' => 'open_marketplace.ui.description', + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => Vendor::class, + 'validation_groups' => $this->validationGroups, + ]); + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Form/Type/VendorShippingMethodChoiceType.php b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/VendorShippingMethodChoiceType.php new file mode 100644 index 0000000..637b632 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/VendorShippingMethodChoiceType.php @@ -0,0 +1,80 @@ +addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options): void { + /** @var VendorInterface $vendor */ + $vendor = $options['vendor']; + /** @var ChannelInterface $channel */ + $channel = $options['channel']; + + $data = []; + /** @var VendorShippingMethod $method */ + foreach ($vendor->getShippingMethods() as $method) { + if ($method->getChannelCode() === $channel->getCode()) { + $data[] = $method->getShippingMethod(); + } + } + $event->setData($data); + }) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver + ->setDefaults([ + 'choices' => fn (Options $options) => $this->shippingMethodRepository->findEnabledForChannel($options['channel']), + 'choice_value' => 'code', + 'choice_label' => 'name', + 'choice_translation_domain' => false, + ]) + ->setRequired('channel') + ->setAllowedTypes('channel', [ChannelInterface::class]) + + ->setRequired('vendor') + ->setAllowedTypes('vendor', [VendorInterface::class]) + ; + } + + public function getParent(): string + { + return ChoiceType::class; + } + + public function getBlockPrefix(): string + { + return 'open_marketplace_shipping_method_choice'; + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Form/Type/VendorShippingMethodsType.php b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/VendorShippingMethodsType.php new file mode 100644 index 0000000..f6cc538 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Form/Type/VendorShippingMethodsType.php @@ -0,0 +1,80 @@ +add('channels', ChannelCollectionType::class, [ + 'entry_type' => VendorShippingMethodChoiceType::class, + 'entry_options' => fn (ChannelInterface $channel) => [ + 'required' => true, + 'multiple' => true, + 'label' => $channel->getName(), + 'expanded' => true, + 'channel' => $channel, + 'vendor' => $options['data'], + ], + 'mapped' => false, + 'label' => 'open_marketplace.ui.shipping_methods', + ])->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($options) { + /** @var VendorInterface $vendor */ + $vendor = $options['data']; + + $vendor->getShippingMethods()->clear(); + $this->entityManager->flush(); + + if (isset($event->getData()['channels'])) { + $channels = $event->getData()['channels']; + foreach ($channels as $key => $shippingMethods) { + foreach ($shippingMethods as $code) { + /** @var ShippingMethodInterface $shippingMethod */ + $shippingMethod = $this->shippingMethodRepository->findOneBy(['code' => $code]); + + $vendorShippingMethod = $this + ->vendorShippingMethodFactory + ->createNewWithChannelCodeShippingAndVendor( + $key, + $shippingMethod, + $vendor + ); + $vendor->addShippingMethod($vendorShippingMethod); + } + } + } + }); + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/MenuListener.php b/OpenMarketplace/src/Component/Core/Vendor/MenuListener.php new file mode 100644 index 0000000..43d194a --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/MenuListener.php @@ -0,0 +1,184 @@ +security->getUser(); + $menu = $this->factory->createItem('root'); + $menu->setLabel('open_marketplace.menu.shop.account.vendor.header'); + + $vendor = $user->getVendor(); + + if (null !== $vendor && false === $vendor->isEnabled()) { + $menu + ->addChild('conversations', ['route' => 'open_marketplace_vendor_messaging_conversation_index']) + ->setLabel('open_marketplace.ui.menu.conversations') + ->setLabelAttribute('icon', 'envelope open'); + + return $menu; + } + + if (null === $vendor || !$vendor->isVerified()) { + $menu + ->addChild('new', ['route' => 'open_marketplace_vendor_register_form']) + ->setLabel('open_marketplace.ui.become_a_vendor') + ->setLabelAttribute('icon', 'star'); + } else { + $menu + ->addChild('product_list', ['route' => 'open_marketplace_vendor_product_listings_index']) + ->setLabel('open_marketplace.ui.product_list') + ->setLabelAttribute('icon', 'list'); + + $menu + ->addChild('attributes', ['route' => 'open_marketplace_vendor_attributes_index']) + ->setLabel('open_marketplace.ui.draft_attributes') + ->setLabelAttribute('icon', 'tag'); + + $menu + ->addChild('inventory', ['route' => 'open_marketplace_vendor_inventory_index']) + ->setLabel('open_marketplace.ui.inventory') + ->setLabelAttribute('icon', 'clipboard'); + + $menu + ->addChild('product_reviews', ['route' => 'open_marketplace_vendor_product_review_index']) + ->setLabel('open_marketplace.ui.menu.product_reviews') + ->setLabelAttribute('icon', 'star'); + + $menu + ->addChild('order_list', ['route' => 'open_marketplace_vendor_orders_listing']) + ->setLabel('open_marketplace.ui.order_list') + ->setLabelAttribute('icon', 'suitcase'); + + $menu + ->addChild('clients', ['route' => 'open_marketplace_vendor_customers_index']) + ->setLabel('open_marketplace.ui.clients') + ->setLabelAttribute('icon', 'users'); + + $menu + ->addChild('profile', ['route' => 'open_marketplace_vendor_profile_details']) + ->setLabel('open_marketplace.ui.vendor_profile') + ->setLabelAttribute('icon', 'user'); + $menu + ->addChild('conversations', ['route' => 'open_marketplace_vendor_messaging_conversation_index']) + ->setLabel('open_marketplace.ui.menu.conversations') + ->setLabelAttribute('icon', 'envelope open'); + + $menu + ->addChild('settlements', ['route' => 'open_marketplace_vendor_settlements_index']) + ->setLabel('open_marketplace.ui.settlements') + ->setLabelAttribute('icon', 'money'); + + $menu + ->addChild('shipping', ['route' => 'open_marketplace_vendor_shipping_methods_form']) + ->setLabel('open_marketplace.ui.shipping_methods') + ->setLabelAttribute('icon', 'shipping'); + } + + $eventName = 'open_marketplace.menu.shop.vendor'; + $this->eventDispatcher->dispatch( + new MenuBuilderEvent($this->factory, $menu), + $eventName + ); + + return $menu; + } + + public function addOrderCancelButton(array $options): ItemInterface + { + $menu = $this->factory->createItem('root'); + + if (!isset($options['order'])) { + return $menu; + } + + $order = $options['order']; + + $stateMachine = $this->stateMachineFactory->get($order, OrderTransitions::GRAPH); + if ($this->security->isGranted(OrderOperationVoter::CANCEL, $order)) { + $menu + ->addChild('cancel', [ + 'route' => 'open_marketplace_vendor_orders_cancel', + 'routeParameters' => [ + 'id' => $order->getId(), + '_csrf_token' => $this->csrfTokenManager->getToken((string) $order->getId())->getValue(), + ], + ]) + ->setAttribute('type', 'transition') + ->setAttribute('confirmation', true) + ->setLabel('sylius.ui.cancel') + ->setLabelAttribute('icon', 'ban') + ->setLabelAttribute('color', 'yellow') + ; + } + + $eventName = 'sylius.menu.vendor.order.show'; + $this->eventDispatcher->dispatch( + new OrderShowMenuBuilderEvent($this->factory, $menu, $order, $stateMachine), + $eventName + ); + + return $menu; + } + + public function addShowCustomerOrdersButton(array $options): ItemInterface + { + $menu = $this->factory->createItem('root'); + + if (!isset($options['customer'])) { + return $menu; + } + + $customer = $options['customer']; + $menu + ->addChild('order_index', [ + 'route' => 'open_marketplace_vendor_customers_order_index', + 'routeParameters' => ['id' => $customer->getId()], + ]) + ->setAttribute('type', 'show') + ->setLabel('sylius.ui.show_orders') + ; + + $eventName = 'sylius.menu.vendor.customer.show'; + $this->eventDispatcher->dispatch( + new CustomerShowMenuBuilderEvent($this->factory, $menu, $customer), + $eventName, + ); + + return $menu; + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/config.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/config.yaml new file mode 100644 index 0000000..d2977ec --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/config.yaml @@ -0,0 +1,4 @@ +imports: + - { resource: 'grids/*.yaml' } + - { resource: 'emails/*.yaml' } + - { resource: 'ui/ui.yaml' } diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/emails/activation_token.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/emails/activation_token.yaml new file mode 100644 index 0000000..ba573f4 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/emails/activation_token.yaml @@ -0,0 +1,7 @@ +sylius_mailer: + sender: + name: 'OpenMarketplace' + address: no-reply@bitbag.io + emails: + vendor_profile_update: + template: "Context/Vendor/Email/profileUpdate.html.twig" diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/emails/settlements_created.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/emails/settlements_created.yaml new file mode 100644 index 0000000..5cb4e3c --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/emails/settlements_created.yaml @@ -0,0 +1,7 @@ +sylius_mailer: + sender: + name: 'OpenMarketplace' + address: no-reply@bitbag.io + emails: + settlements_created: + template: "Context/Vendor/Email/settlementsCreated.html.twig" diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/clients.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/clients.yaml new file mode 100644 index 0000000..f20f276 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/clients.yaml @@ -0,0 +1,68 @@ +sylius_grid: + grids: + open_marketplace_vendor_clients: + driver: + name: doctrine/orm + options: + class: "%sylius.model.customer.class%" + repository: + method: findVendorCustomers + arguments: + - "expr:service('bitbag.open_marketplace.component.vendor.context.vendor').getVendor()" + sorting: + createdAt: desc + fields: + firstName: + type: string + label: sylius.ui.first_name + sortable: ~ + lastName: + type: string + label: sylius.ui.last_name + sortable: ~ + email: + type: string + label: sylius.ui.email + sortable: ~ + createdAt: + type: datetime + label: sylius.ui.registration_date + sortable: ~ + options: + format: d-m-Y H:i + enabled: + type: twig + label: sylius.ui.enabled + path: . + options: + template: "@SyliusAdmin/Customer/Grid/Field/enabled.html.twig" + verified: + type: twig + label: sylius.ui.verified + path: . + options: + template: "@SyliusAdmin/Customer/Grid/Field/verified.html.twig" + filters: + search: + type: string + label: sylius.ui.search + options: + fields: [ email, firstName, lastName ] + actions: + item: + show: + type: shop_show + label: sylius.ui.show + options: + link: + route: open_marketplace_vendor_customers_show + parameters: + id: resource.id + show_orders: + type: shop_show + label: sylius.ui.show_orders + options: + link: + route: open_marketplace_vendor_customers_order_index + parameters: + id: resource.id diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/draft_attribute.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/draft_attribute.yaml new file mode 100644 index 0000000..d9cb877 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/draft_attribute.yaml @@ -0,0 +1,56 @@ +sylius_grid: + templates: + action: + render_attribute_types: "Configuration/Grid/Action/createDraftAttribute.html.twig" + grids: + vendor_draft_attribute: + driver: + name: doctrine/orm + options: + class: "%open_marketplace.model.product_draft_attribute.class%" + repository: + method: findVendorDraftAttributesQuery + arguments: + - "expr:service('bitbag.open_marketplace.component.vendor.context.vendor').getVendor()" + sorting: + position: asc + fields: + code: + type: string + label: sylius.ui.code + sortable: ~ + name: + type: string + label: sylius.ui.name + position: + type: string + enabled: false + sortable: ~ + type: + type: twig + label: sylius.ui.type + sortable: ~ + options: + template: "@SyliusUi/Grid/Field/label.html.twig" + translatable: + type: twig + label: sylius.ui.translatable + sortable: ~ + options: + template: "@SyliusUi/Grid/Field/enabled.html.twig" + filters: + code: + type: string + label: sylius.ui.code + translatable: + type: boolean + label: sylius.ui.translatable + actions: + main: + create: + type: render_attribute_types + item: + update: + type: update + delete: + type: delete diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/product_listing.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/product_listing.yaml new file mode 100644 index 0000000..41a68c2 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/product_listing.yaml @@ -0,0 +1,57 @@ +sylius_grid: + templates: + action: + edit_product: "Configuration/Grid/Vendor/Action/editProductListing.html.twig" + grids: + open_marketplace_vendor_product_listing: + driver: + name: doctrine/orm + options: + class: BitBag\OpenMarketplace\Component\ProductListing\Entity\Listing + repository: + method: createQueryBuilderByVendorAndDeleted + arguments: + - "expr:service('bitbag.open_marketplace.component.vendor.context.vendor').getVendor()" + filters: + search: + type: string + form_options: + type: contains + options: + fields: [ 'code' ] + status: + type: product_listing_status + label: open_marketplace.ui.status + fields: + code: + type: string + label: open_marketplace.ui.code + + name: + type: twig + label: open_marketplace.ui.name + path: getLatestDraft + options: + template: "Configuration/Grid/Vendor/Field/productListingProductName.html.twig" + + getLatestDraft.verifiedAt: + type: twig + label: open_marketplace.ui.verified_at + options: + template: "Configuration/Grid/Vendor/Field/productListingVerifiedAt.html.twig" + getLatestDraft.status: + type: twig + label: open_marketplace.ui.status + options: + template: "Configuration/Grid/Common/Field/productListingStatus.html.twig" + actions: + main: + create: + type: create + label: open_marketplace.ui.create_new_product + options: + link: + route: open_marketplace_vendor_product_listings_create + item: + dropdown: + type: product_listing_dropdown diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/product_listing_dropdown.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/product_listing_dropdown.yaml new file mode 100644 index 0000000..39ebbbf --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/product_listing_dropdown.yaml @@ -0,0 +1,4 @@ +sylius_grid: + templates: + action: + product_listing_dropdown: "Configuration/Grid/Vendor/Action/productListingDropdown.html.twig" diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/product_review.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/product_review.yaml new file mode 100644 index 0000000..f6474a2 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/product_review.yaml @@ -0,0 +1,76 @@ +sylius_grid: + templates: + action: + product_review_dropdown: "Configuration/Grid/Vendor/Action/productReviewDropdown.html.twig" + grids: + open_marketplace_vendor_product_review: + driver: + name: doctrine/orm + options: + class: "%sylius.model.product_review.class%" + repository: + method: createVendorReviewsQueryBuilder + arguments: + - "expr:service('bitbag.open_marketplace.component.vendor.context.vendor').getVendor()" + + sorting: + date: desc + + fields: + reviewSubject: + type: string + label: sylius.ui.product + author: + type: string + label: sylius.ui.customer + status: + type: twig + label: sylius.ui.status + options: + template: "@SyliusUi/Grid/Field/state.html.twig" + vars: + labels: "@SyliusAdmin/ProductReview/Label/Status" + sortable: status + rating: + type: string + label: sylius.ui.rating + sortable: rating + date: + type: datetime + label: sylius.ui.date + path: createdAt + sortable: createdAt + options: + format: d-m-Y H:i + + filters: + status: + type: select + label: sylius.ui.status + form_options: + choices: + sylius.ui.new: New + sylius.ui.accepted: accepted + sylius.ui.rejected: rejected + rating: + type: select + label: sylius.ui.rating + form_options: + choices: + 1: 1 + 2: 2 + 3: 3 + 4: 4 + 5: 5 + product: + type: string + label: sylius.ui.product + customer: + type: string + label: sylius.ui.customer + + actions: + item: + dropdown: + type: product_review_dropdown + diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/vendor_account_customer_orders.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/vendor_account_customer_orders.yaml new file mode 100644 index 0000000..691c2c1 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/vendor_account_customer_orders.yaml @@ -0,0 +1,118 @@ +sylius_grid: + grids: + vendor_account_customer_orders: + driver: + name: doctrine/orm + options: + class: "%sylius.model.order.class%" + repository: + method: findOrdersForVendorByCustomer + arguments: + - "expr:service('bitbag.open_marketplace.component.vendor.context.vendor').getVendor()" + - $id + sorting: + checkoutCompletedAt: desc + fields: + number: + type: twig + label: sylius.ui.number + sortable: ~ + options: + template: "@SyliusShop/Account/Order/Grid/Field/number.html.twig" + checkoutCompletedAt: + type: datetime + label: sylius.ui.date + sortable: ~ + options: + format: m/d/Y + total: + type: twig + label: sylius.ui.total + path: . + sortable: total + options: + template: "@SyliusShop/Account/Order/Grid/Field/total.html.twig" + customer: + type: twig + label: sylius.ui.customer + sortable: customer.lastName + options: + template: "@SyliusAdmin/Order/Grid/Field/customer.html.twig" + state: + type: twig + label: sylius.ui.state + sortable: ~ + options: + template: "@SyliusUi/Grid/Field/label.html.twig" + vars: + labels: "@SyliusShop/Account/Order/Label/State" + paymentState: + type: twig + label: sylius.ui.payment_state + sortable: ~ + options: + template: "@SyliusUi/Grid/Field/state.html.twig" + vars: + labels: "@SyliusAdmin/Order/Label/PaymentState" + shippingState: + type: twig + label: sylius.ui.shipping_state + sortable: ~ + options: + template: "@SyliusUi/Grid/Field/state.html.twig" + vars: + labels: "@SyliusAdmin/Order/Label/ShippingState" + filters: + state: + type: select + label: sylius.ui.state + form_options: + choices: + sylius.ui.cancelled: cancelled + sylius.ui.completed: completed + sylius.ui.failed: failed + sylius.ui.new: new + sylius.ui.processing: processing + sylius.ui.refunded: refunded + paymentState: + type: select + label: sylius.ui.payment_state + form_options: + choices: + sylius.ui.awaiting_payment: awaiting_payment + sylius.ui.paid: paid + sylius.ui.cancelled: cancelled + shippingState: + type: select + label: sylius.ui.shipping_state + form_options: + choices: + sylius.ui.cancelled: cancelled + sylius.ui.ready: ready + sylius.ui.shipped: shipped + number: + type: string + label: sylius.ui.number + date: + type: date + label: sylius.ui.date + options: + field: checkoutCompletedAt + inclusive_to: true + shipping_method: + type: entity + label: sylius.ui.shipping_method + options: + fields: [ shipments.method ] + form_options: + class: "%sylius.model.shipping_method.class%" + actions: + item: + show: + type: shop_show + label: sylius.ui.show + options: + link: + route: open_marketplace_vendor_orders_show + parameters: + id: resource.id diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/vendor_account_order.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/vendor_account_order.yaml new file mode 100644 index 0000000..048b146 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/vendor_account_order.yaml @@ -0,0 +1,122 @@ +sylius_grid: + grids: + vendor_account_order: + driver: + name: doctrine/orm + options: + class: "%sylius.model.order.class%" + repository: + method: findAllByVendorQueryBuilder + arguments: + - "expr:service('bitbag.open_marketplace.component.vendor.context.vendor').getVendor()" + sorting: + checkoutCompletedAt: desc + fields: + number: + type: twig + label: sylius.ui.number + sortable: ~ + options: + template: "@SyliusShop/Account/Order/Grid/Field/number.html.twig" + checkoutCompletedAt: + type: datetime + label: sylius.ui.date + sortable: ~ + options: + format: m/d/Y + total: + type: twig + label: sylius.ui.total + path: . + sortable: total + options: + template: "@SyliusShop/Account/Order/Grid/Field/total.html.twig" + customer: + type: twig + label: sylius.ui.customer + sortable: customer.lastName + options: + template: "@SyliusAdmin/Order/Grid/Field/customer.html.twig" + state: + type: twig + label: sylius.ui.state + sortable: ~ + options: + template: "@SyliusUi/Grid/Field/label.html.twig" + vars: + labels: "@SyliusShop/Account/Order/Label/State" + paymentState: + type: twig + label: sylius.ui.payment_state + sortable: ~ + options: + template: "@SyliusUi/Grid/Field/state.html.twig" + vars: + labels: "@SyliusAdmin/Order/Label/PaymentState" + shippingState: + type: twig + label: sylius.ui.shipping_state + sortable: ~ + options: + template: "@SyliusUi/Grid/Field/state.html.twig" + vars: + labels: "@SyliusAdmin/Order/Label/ShippingState" + filters: + state: + type: select + label: sylius.ui.state + form_options: + choices: + sylius.ui.cancelled: cancelled + sylius.ui.completed: completed + sylius.ui.failed: failed + sylius.ui.new: new + sylius.ui.processing: processing + sylius.ui.refunded: refunded + paymentState: + type: select + label: sylius.ui.payment_state + form_options: + choices: + sylius.ui.awaiting_payment: awaiting_payment + sylius.ui.paid: paid + sylius.ui.cancelled: cancelled + shippingState: + type: select + label: sylius.ui.shipping_state + form_options: + choices: + sylius.ui.cancelled: cancelled + sylius.ui.ready: ready + sylius.ui.shipped: shipped + number: + type: string + label: sylius.ui.number + customer: + type: string + label: sylius.ui.customer + options: + fields: [ customer.email, customer.firstName, customer.lastName ] + date: + type: date + label: sylius.ui.date + options: + field: checkoutCompletedAt + inclusive_to: true + shipping_method: + type: entity + label: sylius.ui.shipping_method + options: + fields: [ shipments.method ] + form_options: + class: "%sylius.model.shipping_method.class%" + actions: + item: + show: + type: shop_show + label: sylius.ui.show + options: + link: + route: open_marketplace_vendor_orders_show + parameters: + id: resource.id diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/vendor_account_settlement.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/vendor_account_settlement.yaml new file mode 100644 index 0000000..8963e81 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/vendor_account_settlement.yaml @@ -0,0 +1,73 @@ +sylius_grid: + templates: + action: + accept: "Configuration/Grid/Vendor/Action/accept.html.twig" + grids: + vendor_account_settlement: + driver: + name: doctrine/orm + options: + class: '%open_marketplace.model.settlement.class%' + repository: + method: findAllByVendorQueryBuilder + arguments: + - "expr:service('bitbag.open_marketplace.component.vendor.context.vendor').getVendor()" + sorting: + fields: + channel: + type: twig + label: sylius.ui.channel + sortable: channel.code + options: + template: "@SyliusAdmin/Order/Grid/Field/channel.html.twig" + period: + type: twig + label: open_marketplace.ui.period + path: . + options: + template: "Configuration/Grid/Admin/Field/settlementPeriod.html.twig" + totalAmount: + type: twig + label: open_marketplace.ui.total_amount + path: . + options: + template: "Configuration/Grid/Admin/Field/settlementTotals.html.twig" + vars: + method: getTotalAmount + totalCommissionAmount: + type: twig + label: open_marketplace.ui.total_commission_amount + path: . + options: + template: "Configuration/Grid/Admin/Field/settlementTotals.html.twig" + vars: + method: getTotalCommissionAmount + totalProfitAmount: + type: twig + label: open_marketplace.ui.total_profit_amount + path: . + options: + template: "Configuration/Grid/Admin/Field/settlementTotals.html.twig" + vars: + method: getTotalProfitAmount + status: + type: twig + label: open_marketplace.ui.status + options: + template: "Configuration/Grid/Admin/Field/settlementStatus.html.twig" + filters: + channel: + type: entities + label: sylius.ui.channel + form_options: + class: "%sylius.model.channel.class%" + options: + field: "channel.id" + status: + type: settlement_status + label: open_marketplace.ui.status + actions: + item: + accept: + type: accept + label: open_marketplace.ui.accept diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/vendor_product_variants.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/vendor_product_variants.yaml new file mode 100644 index 0000000..8120cbf --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/vendor_product_variants.yaml @@ -0,0 +1,68 @@ +sylius_grid: + grids: + vendor_product_variant: + driver: + name: doctrine/orm + options: + class: "%sylius.model.product_variant.class%" + repository: + method: createQueryBuilderByVendor + arguments: + - "expr:service('bitbag.open_marketplace.component.vendor.context.vendor').getVendor()" + sorting: + position: asc + fields: + name: + type: twig + path: . + label: sylius.ui.name + options: + template: "@SyliusAdmin/ProductVariant/Grid/Field/name.html.twig" + code: + type: string + label: sylius.ui.code + inventory: + type: twig + path: . + label: sylius.ui.inventory + options: + template: "@SyliusAdmin/ProductVariant/Grid/Field/inventory.html.twig" + position: + type: twig + label: sylius.ui.position + path: . + sortable: position + options: + template: "@SyliusAdmin/ProductVariant/Grid/Field/position.html.twig" + filters: + code: + type: string + label: sylius.ui.code + name: + type: string + label: sylius.ui.name + options: + fields: [ translations.name ] + actions: + main: + generate: + type: generate_variants + options: + product: expr:service('sylius.repository.product').find($productId) + update_positions: + type: update_product_variant_positions + create: + type: create + options: + link: + parameters: + productId: $productId + item: + update: + type: update + options: + link: + route: open_marketplace_vendor_inventory_update + parameters: + id: resource.id + productId: $productId diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/virtual_wallet.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/virtual_wallet.yaml new file mode 100644 index 0000000..2f1523c --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/grids/virtual_wallet.yaml @@ -0,0 +1,35 @@ +sylius_grid: + templates: + action: + withdraw: "Configuration/Grid/Vendor/Action/withdraw.html.twig" + grids: + vendor_account_virtual_wallet_index: + driver: + name: doctrine/orm + options: + class: '%open_marketplace.model.virtual_wallet.class%' + repository: + method: findAllByVendorQueryBuilder + arguments: + - "expr:service('bitbag.open_marketplace.component.vendor.context.vendor').getVendor()" + sorting: + fields: + channel: + type: twig + label: sylius.ui.channel + sortable: channel.code + options: + template: "@SyliusAdmin/Order/Grid/Field/channel.html.twig" + balance: + type: twig + label: open_marketplace.ui.balance + path: . + options: + template: "Configuration/Grid/Vendor/Field/money.html.twig" + vars: + method: getBalance + actions: + item: + withdraw: + type: withdraw + label: open_marketplace.ui.withdraw_funds diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/routing.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing.yaml new file mode 100644 index 0000000..f4db73f --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing.yaml @@ -0,0 +1,39 @@ +open_marketplace_vendor_attributes: + resource: "routing/attributes.yaml" + +open_marketplace_vendor_customers: + resource: "routing/customers.yaml" + +open_marketplace_vendor_inventory: + resource: "routing/inventory.yaml" + +open_marketplace_vendor_messaging: + resource: "routing/messaging.yaml" + +open_marketplace_vendor_orders: + resource: "routing/orders.yaml" + +open_marketplace_vendor_settlements: + resource: "routing/settlements.yaml" + +open_marketplace_vendor_product_listings: + resource: "routing/product_listings.yaml" + +open_marketplace_vendor_profile: + resource: "routing/profile.yaml" + +open_marketplace_vendor_register: + resource: "routing/register.yaml" + +open_marketplace_vendor_reviews: + resource: "routing/reviews.yaml" + +open_marketplace_vendor_shipping_methods: + resource: "routing/shipping_methods.yaml" + +open_marketplace_vendor_taxonomy: + resource: "routing/taxonomy.yaml" + prefix: /taxons + +open_marketplace_vendor_virtual_wallet: + resource: "routing/virtual_wallet.yaml" diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/attributes.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/attributes.yaml new file mode 100644 index 0000000..459447c --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/attributes.yaml @@ -0,0 +1,77 @@ +open_marketplace_vendor_attributes_index: + path: /product-attributes + methods: [ GET, POST ] + defaults: + _controller: open_marketplace.controller.product_draft_attribute:indexAction + _sylius: + template: "Context/Vendor/DraftAttributes/index.html.twig" + grid: vendor_draft_attribute + +open_marketplace_vendor_attributes_create: + path: /product-attributes/{type}/new + methods: [ GET, POST ] + defaults: + _controller: bitbag.open_marketplace.component.core.common.controller.resource.draft_attribute:createAction + _sylius: + factory: + method: createTyped + arguments: + type: $type + template: "Context/Vendor/DraftAttributes/create.html.twig" + redirect: open_marketplace_vendor_attributes_index + permission: true + vars: + subheader: sylius.ui.manage_attributes_of_your_products + templates: + form: "@SyliusAdmin/ProductAttribute/_form.html.twig" + route: + parameters: + type: $type + +open_marketplace_product_draft_attribute_update: + path: /product-attributes/{id}/update + defaults: + _controller: bitbag.open_marketplace.component.core.common.controller.resource.draft_attribute:updateAction + _sylius: + template: "Context/Vendor/DraftAttributes/update.html.twig" + redirect: open_marketplace_vendor_attributes_index + vars: + templates: + form: "@SyliusAdmin/ProductAttribute/_form.html.twig" + route: + parameters: + id: $id + +open_marketplace_vendor_attributes_update: + alias: open_marketplace_product_draft_attribute_update + +open_marketplace_product_draft_attribute_delete: + path: /product-attributes/{id}/delete + defaults: + _controller: bitbag.open_marketplace.component.core.common.controller.resource.draft_attribute:deleteAction + _sylius: + redirect: open_marketplace_vendor_attributes_index + +open_marketplace_vendor_attributes_delete: + alias: open_marketplace_product_draft_attribute_delete + +open_marketplace_vendor_attributes_types: + path: /attribute-types + methods: [ GET ] + defaults: + _controller: bitbag.open_marketplace.component.core.common.controller.resource.draft_attribute:getAttributeTypesAction + template: "Context/Vendor/DraftAttributes/attributeTypes.html.twig" + +open_marketplace_vendor_attributes_listing: + path: /attributes + methods: [ GET ] + defaults: + _controller: bitbag.open_marketplace.component.core.common.controller.resource.draft_attribute:renderAttributesAction + template: "Context/Vendor/ProductListing/form/_attributeChoice.html.twig" + +open_marketplace_vendor_attributes_render_forms: + path: /attribute-forms + methods: [ GET ] + defaults: + _controller: bitbag.open_marketplace.component.core.common.controller.resource.draft_attribute:renderAttributeValueFormsAction + template: "Context/Vendor/ProductListing/form/attributeValues.html.twig" diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/customers.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/customers.yaml new file mode 100644 index 0000000..45b24b8 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/customers.yaml @@ -0,0 +1,33 @@ +open_marketplace_vendor_customers_index: + path: /customers + defaults: + _controller: sylius.controller.customer:indexAction + _sylius: + template: "Context/Vendor/Customers/index.html.twig" + grid: open_marketplace_vendor_clients + +open_marketplace_vendor_customers_show: + path: /customers/{id} + methods: [ GET ] + defaults: + id: 0 + _controller: sylius.controller.customer:showAction + _sylius: + permission: true + template: "Context/Vendor/Customers/show.html.twig" + repository: + method: findCustomerForVendor + arguments: + - "expr:service('bitbag.open_marketplace.component.vendor.context.vendor').getVendor()" + - $id + +open_marketplace_vendor_customers_order_index: + path: /customers/{id}/orders + methods: [ GET ] + defaults: + _controller: sylius.controller.order:indexAction + _sylius: + section: admin + permission: true + template: "Context/Vendor/Order/index.html.twig" + grid: vendor_account_customer_orders diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/inventory.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/inventory.yaml new file mode 100644 index 0000000..2bcecee --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/inventory.yaml @@ -0,0 +1,39 @@ +open_marketplace_vendor_inventory_index: + path: /product-variants/inventory + methods: [ GET ] + defaults: + _controller: sylius.controller.product_variant:indexAction + _sylius: + template: "Context/Vendor/Inventory/index.html.twig" + grid: vendor_product_variant + vars: + route: + parameters: + productId: $productId + templates: + breadcrumb: "@SyliusAdmin/ProductVariant/Index/_breadcrumb.html.twig" + icon: cubes + subheader: sylius.ui.manage_variants + +open_marketplace_vendor_inventory_update: + path: /product-variants/{id}/inventory + methods: [ GET, PUT ] + defaults: + _controller: sylius.controller.product_variant:updateAction + _sylius: + template: "Context/Vendor/Inventory/update.html.twig" + grid: sylius_admin_product_variant + redirect: + route: open_marketplace_vendor_inventory_index + repository: + method: findOneById + arguments: + id: $id + vars: + route: + parameters: + id: $id + templates: + form: "@SyliusAdmin/ProductVariant/_form.html.twig" + breadcrumb: "@SyliusAdmin/ProductVariant/Update/_breadcrumb.html.twig" + toolbar: "@SyliusAdmin/ProductVariant/Update/_toolbar.html.twig" diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/messaging.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/messaging.yaml new file mode 100644 index 0000000..0fa914e --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/messaging.yaml @@ -0,0 +1,46 @@ +open_marketplace_vendor_messaging_conversation_index: + path: /conversations + methods: [ GET ] + defaults: + _controller: bitbag.open_marketplace.component.core.vendor.controller.messaging.list_threads + _sylius: + template: "Context/Vendor/Conversation/index.html.twig" + +open_marketplace_vendor_messaging_conversation_show: + path: /conversations/{id} + methods: [ GET,POST ] + defaults: + _controller: bitbag.open_marketplace.component.core.common.controller.messaging.show_thread + _sylius: + template: "Context/Vendor/Conversation/show.html.twig" + +open_marketplace_vendor_messaging_conversation_message_add: + path: /conversations/{id}/message/add + methods: [ GET, POST ] + defaults: + _controller: bitbag.open_marketplace.component.core.common.controller.messaging.create_message + _sylius: + redirect: open_marketplace_vendor_messaging_conversation_show + mail_redirect: open_marketplace_vendor_messaging_conversation_show + +open_marketplace_vendor_messaging_conversation_create: + path: /conversation/create + methods: [ GET,POST ] + defaults: + _controller: bitbag.open_marketplace.component.core.common.controller.messaging.create_thread + _sylius: + template: "Context/Vendor/Conversation/create.html.twig" + redirect: open_marketplace_vendor_messaging_conversation_show + mail_redirect: open_marketplace_admin_messaging_conversation_show + +open_marketplace_vendor_messaging_conversation_archive: + path: /conversations/{id}/archive + methods: [ PATCH ] + defaults: + _controller: open_marketplace.controller.conversation:applyStateMachineTransitionAction + _sylius: + state_machine: + graph: open_marketplace_conversation + transition: close + redirect: referer + flash: open_marketplace.ui.conversation_successfully_closed diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/orders.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/orders.yaml new file mode 100644 index 0000000..6f795ae --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/orders.yaml @@ -0,0 +1,64 @@ +open_marketplace_vendor_orders_listing: + path: /orders + methods: [ GET ] + defaults: + _controller: sylius.controller.order:indexAction + _sylius: + template: "Context/Vendor/Order/index.html.twig" + grid: vendor_account_order + +open_marketplace_vendor_orders_show: + path: /orders/{id} + methods: [ GET ] + defaults: + _controller: sylius.controller.order:showAction + _sylius: + section: admin + permission: true + template: "Context/Vendor/Order/show.html.twig" + repository: + method: findOrderForVendor + arguments: + - "expr:service('bitbag.open_marketplace.component.vendor.context.vendor').getVendor()" + - $id + +open_marketplace_vendor_orders_cancel: + path: /{id}/cancel + methods: [ PUT ] + defaults: + _controller: open_marketplace.controller.order.order_controller:applyStateMachineTransitionAction + _sylius: + permission: true + state_machine: + graph: sylius_order + transition: cancel + redirect: referer + +open_marketplace_vendor_orders_resend_confirmation_email: + path: /{id}/resend-confirmation-email + methods: [ GET ] + defaults: + _controller: bitbag.open_marketplace.component.core.vendor.controller.order.resend_confirmation_email + +open_marketplace_vendor_orders_shipment_ship: + path: /orders/{orderId}/shipments/{id}/ship + methods: [ PUT ] + defaults: + _controller: sylius.controller.shipment:updateAction + _sylius: + event: ship + repository: + method: findOneByOrderId + arguments: + id: $id + orderId: $orderId + state_machine: + graph: sylius_shipment + transition: ship + redirect: referer + form: Sylius\Bundle\ShippingBundle\Form\Type\ShipmentShipType + vars: + route: + parameters: + orderId: $orderId + id: $id diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/product_listings.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/product_listings.yaml new file mode 100644 index 0000000..8192168 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/product_listings.yaml @@ -0,0 +1,58 @@ +open_marketplace_vendor_product_listings_index: + path: /product-listings + methods: [ GET ] + defaults: + _controller: open_marketplace.controller.product_listing:indexAction + _sylius: + template: "Context/Vendor/ProductListing/index.html.twig" + grid: open_marketplace_vendor_product_listing + +open_marketplace_vendor_product_listings_create: + path: /product-listings/create + methods: [ GET,POST ] + defaults: + _controller: bitbag.open_marketplace.component.core.vendor.controller.product_listing.create + _sylius: + template: "Context/Vendor/ProductListing/create.html.twig" + redirect: + route: open_marketplace_vendor_inventory_index + +open_marketplace_vendor_product_listings_edit: + path: /product-listings/{id}/edit + methods: [ GET,POST ] + defaults: + _controller: bitbag.open_marketplace.component.core.vendor.controller.product_listing.update + _sylius: + template: "Context/Vendor/ProductListing/update.html.twig" + redirect: + route: open_marketplace_vendor_inventory_index + +open_marketplace_vendor_product_listings_show: + path: /product-listings/{id} + methods: [ GET,POST ] + defaults: + _controller: open_marketplace.controller.product_draft:showAction + _sylius: + template: 'Context/Vendor/ProductListing/details.html.twig' + +open_marketplace_vendor_product_listings_send_for_verification: + path: /product-listings/{id}/send-for-verification + methods: [ POST ] + defaults: + _controller: bitbag.open_marketplace.component.core.vendor.controller.product_listing.send_for_verification + +open_marketplace_vendor_product_listings_remove: + path: /product-listings-hide/{id} + methods: [ POST ] + defaults: + _controller: bitbag.open_marketplace.component.core.vendor.controller.product_listing.remove + _sylius: + template: "Context/Vendor/ProductListing/index.html.twig" + redirect: + route: open_marketplace_vendor_inventory_index + +open_marketplace_vendor_product_listings_enable: + path: /product-listings/{id}/enable + methods: [ POST ] + defaults: + _controller: bitbag.open_marketplace.component.core.vendor.controller.product_listing.enable diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/profile.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/profile.yaml new file mode 100644 index 0000000..b19e201 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/profile.yaml @@ -0,0 +1,35 @@ +open_marketplace_vendor_profile_details: + path: /profile + methods: [ GET ] + defaults: + _controller: bitbag.open_marketplace.component.core.common.controller.resource.vendor:showVendorProfileAction + _sylius: + template: "Context/Vendor/Profile/index.html.twig" + +open_marketplace_vendor_profile_update: + path: /profile/update + methods: [ GET, POST ] + defaults: + autowire: true + _controller: bitbag.open_marketplace.component.core.common.controller.resource.vendor:customUpdateAction + _sylius: + template: "Context/Vendor/Profile/update.html.twig" + form: BitBag\OpenMarketplace\Component\Core\Vendor\Form\Type\Profile\ProfileType + event: update + flash: open_marketplace.ui.vendor_updated + redirect: + route: sylius_shop_account_dashboard + +open_marketplace_vendor_profile_confirm_link: + path: /profile-update/{token} + methods: [ GET ] + defaults: + _controller: bitbag.open_marketplace.component.core.vendor.controller.profile.confirm_update + _sylius: + template: "Context/Vendor/Profile/update.html.twig" + form: BitBag\OpenMarketplace\Component\Core\Vendor\Form\Type\Profile\ProfileType + event: update + repository: + method: findOneByActivationToken + arguments: + token: $token diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/register.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/register.yaml new file mode 100644 index 0000000..54fa7a7 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/register.yaml @@ -0,0 +1,13 @@ +open_marketplace_vendor_register_form: + path: /register + methods: [ GET, POST ] + requirements: + _locale: ^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$ + defaults: + _controller: open_marketplace.controller.vendor:createAction + _sylius: + template: 'Context/Vendor/Register/index.html.twig' + form: BitBag\OpenMarketplace\Component\Core\Vendor\Form\Type\Profile\ProfileType + redirect: + route: open_marketplace_vendor_register_form + flash: vendor.vendor_register diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/reviews.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/reviews.yaml new file mode 100644 index 0000000..491cb24 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/reviews.yaml @@ -0,0 +1,50 @@ +open_marketplace_vendor_product_review_index: + path: /product-reviews + methods: [ GET ] + defaults: + _controller: sylius.controller.product_review:indexAction + _sylius: + template: "Context/Vendor/ProductReviews/index.html.twig" + grid: open_marketplace_vendor_product_review + +open_marketplace_vendor_product_review_edit: + path: /product-reviews/{id}/edit + methods: [ GET, POST ] + defaults: + _controller: sylius.controller.product_review:updateAction + _sylius: + template: "Context/Vendor/ProductReviews/update.html.twig" + redirect: open_marketplace_vendor_product_review_index + form: BitBag\OpenMarketplace\Component\Core\Vendor\Form\Type\ProductReviewType + +open_marketplace_vendor_product_review_delete: + path: /product-reviews/{id}/delete + methods: [ DELETE ] + defaults: + _controller: sylius.controller.product_review:deleteAction + _sylius: + redirect: referer + +open_marketplace_vendor_product_review_accept: + path: /product-review/{id}/accept + methods: [ PATCH ] + defaults: + _controller: sylius.controller.product_review:applyStateMachineTransitionAction + _sylius: + state_machine: + graph: sylius_product_review + transition: accept + redirect: referer + flash: sylius.review.accept + +open_marketplace_vendor_product_review_reject: + path: /product-review/{id}/reject + methods: [ PATCH ] + defaults: + _controller: sylius.controller.product_review:applyStateMachineTransitionAction + _sylius: + state_machine: + graph: sylius_product_review + transition: reject + redirect: referer + flash: sylius.review.reject diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/settlements.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/settlements.yaml new file mode 100644 index 0000000..5363ce2 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/settlements.yaml @@ -0,0 +1,20 @@ +open_marketplace_vendor_settlements_index: + path: /settlements + methods: [ GET ] + defaults: + _controller: open_marketplace.controller.settlement:indexAction + _sylius: + template: "Context/Vendor/Settlement/index.html.twig" + grid: vendor_account_settlement + +open_marketplace_vendor_settlement_settle: + path: /settlements/{id}/settle + methods: [ POST ] + defaults: + _controller: open_marketplace.controller.settlement:applyStateMachineTransitionAction + _sylius: + state_machine: + graph: open_marketplace_settlement + transition: accept + redirect: referer + flash: open_marketplace.ui.settlement_accepted diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/shipping_methods.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/shipping_methods.yaml new file mode 100644 index 0000000..ec97cf5 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/shipping_methods.yaml @@ -0,0 +1,16 @@ +open_marketplace_vendor_shipping_methods_form: + path: /shipping-methods + methods: [ GET, POST ] + defaults: + _controller: bitbag.open_marketplace.component.core.common.controller.resource.vendor:updateAction + _sylius: + template: 'Context/Vendor/ShippingMethods/index.html.twig' + form: BitBag\OpenMarketplace\Component\Core\Vendor\Form\Type\VendorShippingMethodsType + event: update + repository: + method: findOneById + arguments: + id: "expr:service('bitbag.open_marketplace.component.vendor.context.vendor').getVendor().getId()" + flash: open_marketplace.ui.shipping_method_updated + redirect: + route: open_marketplace_vendor_shipping_methods_form diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/taxonomy.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/taxonomy.yaml new file mode 100644 index 0000000..340dec4 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/taxonomy.yaml @@ -0,0 +1,75 @@ +open_marketplace_vendor_taxonomy_ajax_taxon_root_nodes: + path: /root-nodes + methods: [ GET ] + defaults: + _controller: sylius.controller.taxon:indexAction + _format: json + _sylius: + serialization_groups: [ Autocomplete ] + permission: true + repository: + method: findRootNodes + +open_marketplace_vendor_taxonomy_ajax_taxon_leafs: + path: /leafs + methods: [ GET ] + defaults: + _controller: sylius.controller.taxon:indexAction + _format: json + _sylius: + serialization_groups: [ Autocomplete ] + permission: true + repository: + method: findChildren + arguments: + parentCode: $parentCode + +open_marketplace_vendor_taxonomy_ajax_taxon_by_code: + path: /leaf + methods: [ GET ] + defaults: + _controller: sylius.controller.taxon:indexAction + _format: json + _sylius: + serialization_groups: [ Autocomplete ] + permission: true + repository: + method: findBy + arguments: [ code: $code ] + +open_marketplace_vendor_taxonomy_ajax_taxon_by_name_phrase: + path: /search + methods: [ GET ] + defaults: + _controller: sylius.controller.taxon:indexAction + _format: json + _sylius: + serialization_groups: [ Autocomplete ] + permission: true + repository: + method: findByNamePart + arguments: + phrase: expr:service('request_stack').getCurrentRequest().query.get('phrase', '') + locale: null + limit: 25 + +open_marketplace_vendor_taxonomy_ajax_generate_taxon_slug: + path: /generate-slug/ + methods: [ GET ] + requirements: + _locale: ^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$ + defaults: + _controller: sylius.controller.taxon_slug:generateAction + _format: json + +open_marketplace_vendor_taxonomy_ajax_taxon_move: + path: /{id}/move + methods: [ PUT ] + requirements: + _locale: ^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$ + defaults: + _controller: sylius.controller.taxon:updateAction + _format: json + _sylius: + permission: true + form: Sylius\Bundle\TaxonomyBundle\Form\Type\TaxonPositionType diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/virtual_wallet.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/virtual_wallet.yaml new file mode 100644 index 0000000..8882de9 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/routing/virtual_wallet.yaml @@ -0,0 +1,18 @@ +open_marketplace_vendor_virtual_wallet_index: + path: /virtual-wallets + methods: [ GET ] + defaults: + _controller: open_marketplace.controller.virtual_wallet:indexAction + _sylius: + template: "Context/Vendor/VirtualWallet/index.html.twig" + grid: vendor_account_virtual_wallet_index + +open_marketplace_vendor_profit_withdrawal_create: + path: /profit-withdrawal/{channelCode} + methods: [ GET, POST ] + defaults: + _controller: bitbag.open_marketplace.component.core.settlement.controller.action.profit_withdrawal + _sylius: + template: "Context/Vendor/Settlement/create.html.twig" + event: profit_withdrawal_create + form: BitBag\OpenMarketplace\Component\Core\Settlement\Form\ProfitWithdrawalType diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/services.xml b/OpenMarketplace/src/Component/Core/Vendor/Resources/services.xml new file mode 100644 index 0000000..2a3c7de --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/services.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/services/controllers.xml b/OpenMarketplace/src/Component/Core/Vendor/Resources/services/controllers.xml new file mode 100644 index 0000000..e9f275a --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/services/controllers.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + open_marketplace.product_draft + + + + + + + + + + + + + + + + + + + + + open_marketplace.product_draft + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/services/event_listeners.xml b/OpenMarketplace/src/Component/Core/Vendor/Resources/services/event_listeners.xml new file mode 100644 index 0000000..2c77ad1 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/services/event_listeners.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/services/factories.xml b/OpenMarketplace/src/Component/Core/Vendor/Resources/services/factories.xml new file mode 100644 index 0000000..7bc466b --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/services/factories.xml @@ -0,0 +1,19 @@ + + + + + + + + + + BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftTaxon + + + diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/services/form_types.xml b/OpenMarketplace/src/Component/Core/Vendor/Resources/services/form_types.xml new file mode 100644 index 0000000..7213800 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/services/form_types.xml @@ -0,0 +1,139 @@ + + + + + + + + Default + VendorUserRegister + VendorLogo + sylius + + + + + + + BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor + %open_marketplace.form.type.vendor.validation_groups% + + + + + + BitBag\OpenMarketplace\Component\Vendor\Entity\BackgroundImage + + + + + BitBag\OpenMarketplace\Component\Vendor\Entity\LogoImage + + + + + %sylius.model.product_review.class% + + + + + + + + BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor + + + + + + + + + + BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttribute + %sylius.form.type.product_attribute.validation_groups% + BitBag\OpenMarketplace\Component\Core\Vendor\Form\Type\ProductListing\DraftAttributeTranslationType + + + + + + BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttributeTranslation + %sylius.form.type.product_attribute_translation.validation_groups% + + + + + + + + + + + BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttributeValue + %sylius.form.type.product_attribute_value.validation_groups% + BitBag\OpenMarketplace\Component\Core\Vendor\Form\Type\ProductListing\DraftAttributeChoiceType + + + + + + + + + + + + + + + + + + + + + + %open_marketplace.model.product_listing_price.class% + %sylius.form.type.channel_pricing.validation_groups% + + + + + + BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftImage + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/services/twig_extensions.xml b/OpenMarketplace/src/Component/Core/Vendor/Resources/services/twig_extensions.xml new file mode 100644 index 0000000..b52c3f2 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/services/twig_extensions.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/services/voters.xml b/OpenMarketplace/src/Component/Core/Vendor/Resources/services/voters.xml new file mode 100644 index 0000000..fd7efe3 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/services/voters.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Core/Vendor/Resources/ui/ui.yaml b/OpenMarketplace/src/Component/Core/Vendor/Resources/ui/ui.yaml new file mode 100644 index 0000000..f9b9fda --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Resources/ui/ui.yaml @@ -0,0 +1,81 @@ +sylius_ui: + events: + open_marketplace.admin.vendor.show.details: + blocks: + content: + template: 'Configuration/Event/Admin/Vendor/Show/details.html.twig' + priority: 10 + open_marketplace.admin.vendor.show.details_content: + blocks: + labels: + template: 'Configuration/Event/Admin/Vendor/Show/detailsLabels.html.twig' + priority: 20 + table: + template: 'Configuration/Event/Admin/Vendor/Show/detailsTable.html.twig' + priority: 10 + open_marketplace.admin.vendor.form: + blocks: + content: + template: 'Configuration/Event/Admin/Vendor/Update/content.html.twig' + priority: 10 + open_marketplace.admin.vendor.form.content: + blocks: + content: + template: 'Configuration/Event/Admin/Vendor/Update/columns.html.twig' + priority: 10 + open_marketplace.admin.vendor.form.first_column: + blocks: + content: + template: 'Configuration/Event/Admin/Vendor/Update/firstColumn.html.twig' + priority: 10 + open_marketplace.admin.vendor.form.vendor_details: + blocks: + content: + template: 'Configuration/Event/Admin/Vendor/Update/_details.html.twig' + priority: 10 + open_marketplace.admin.vendor.form.vendor_commission: + blocks: + content: + template: 'Configuration/Event/Admin/Vendor/Update/_commission.html.twig' + priority: 10 + open_marketplace.admin.vendor.form.vendor_settlement: + blocks: + content: + template: 'Configuration/Event/Admin/Vendor/Update/_settlement.html.twig' + priority: 10 + open_marketplace.admin.vendor.form.second_column: + blocks: + content: + template: 'Configuration/Event/Admin/Vendor/Update/secondColumn.html.twig' + priority: 10 + open_marketplace.admin.vendor.form.vendor_address: + blocks: + content: + template: 'Configuration/Event/Admin/Vendor/Update/vendorAddress.html.twig' + priority: 10 + sylius.shop.account.layout.menu: + blocks: + vendor: + template: "Configuration/Event/Shop/Account/Menu/content.html.twig" + priority: 7 + open_marketplace.shop.product.index.search: + blocks: + before_search_legacy: + template: "@SyliusUi/Block/_legacySonataEvent.html.twig" + priority: 35 + context: + event: sylius.shop.product.index.before_search + search: + template: "Context/Vendor/VendorPage/_search.html.twig" + priority: 30 + after_search_legacy: + template: "@SyliusUi/Block/_legacySonataEvent.html.twig" + priority: 25 + context: + event: sylius.shop.product.index.after_search + pagination: + template: "@SyliusShop/Product/Index/_pagination.html.twig" + priority: 20 + sorting: + template: "@SyliusShop/Product/Index/_sorting.html.twig" + priority: 10 diff --git a/OpenMarketplace/src/Component/Core/Vendor/Security/Voter/OrderOperationVoter.php b/OpenMarketplace/src/Component/Core/Vendor/Security/Voter/OrderOperationVoter.php new file mode 100644 index 0000000..09e7b83 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Security/Voter/OrderOperationVoter.php @@ -0,0 +1,68 @@ + $this->canCancel($subject), + default => throw new \LogicException(sprintf('Unsupported attribute: "%s"', $attribute)) + }; + } + + private function canCancel(OrderInterface $order): bool + { + $stateMachine = $this->stateMachineFactory->get($order, OrderTransitions::GRAPH); + + return $stateMachine->can(OrderTransitions::TRANSITION_CANCEL) + && OrderPaymentStates::STATE_PAID === $order->getPaymentState(); + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Security/Voter/TokenOwningVoter.php b/OpenMarketplace/src/Component/Core/Vendor/Security/Voter/TokenOwningVoter.php new file mode 100644 index 0000000..1424caf --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Security/Voter/TokenOwningVoter.php @@ -0,0 +1,69 @@ +getUser(); + if (!$user instanceof ShopUserInterface || null == $subject) { + return false; + } + + /** @var ProfileUpdateInterface $vendorUpdateData */ + $vendorUpdateData = $subject; + + switch ($attribute) { + case self::UPDATE: + return $this->doesUserOwnTheData($vendorUpdateData, $user); + default: + return false; + } + } + + private function doesUserOwnTheData(ProfileUpdateInterface $profileUpdate, ShopUserInterface $user): bool + { + $loggedInVendor = $user->getVendor(); + $vendorData = $profileUpdate->getVendor(); + if ($loggedInVendor === $vendorData) { + return true; + } + + return false; + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Twig/Extension/VendorClientExtension.php b/OpenMarketplace/src/Component/Core/Vendor/Twig/Extension/VendorClientExtension.php new file mode 100644 index 0000000..994bfda --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Twig/Extension/VendorClientExtension.php @@ -0,0 +1,41 @@ +customerRepository = $customerRepository; + } + + public function getFunctions(): array + { + return [ + new TwigFunction('is_vendor_client', [$this, 'isVendorClient']), + ]; + } + + public function isVendorClient(VendorInterface $vendor, CustomerInterface $customer): bool + { + $client = $this->customerRepository->findCustomerForVendor($vendor, (string) $customer->getId()); + + return null !== $client; + } +} diff --git a/OpenMarketplace/src/Component/Core/Vendor/Twig/Extension/VendorExtension.php b/OpenMarketplace/src/Component/Core/Vendor/Twig/Extension/VendorExtension.php new file mode 100644 index 0000000..1fdedf1 --- /dev/null +++ b/OpenMarketplace/src/Component/Core/Vendor/Twig/Extension/VendorExtension.php @@ -0,0 +1,103 @@ +vendorProvider = $vendorProvider; + $this->manager = $manager; + $this->localeContext = $localeContext; + $this->channelRepository = $channelRepository; + $this->channelContext = $channelContext; + } + + public function getFunctions(): array + { + return [ + new TwigFunction('is_pending_vendor_profile_update', [$this, 'isPendingVendorProfileUpdate']), + new TwigFunction('has_vendor_virtual_wallet_strategy', [$this, 'hasVirtualWalletStrategy']), + new TwigFunction('current_locale', [$this, 'currentLocale']), + new TwigFunction('get_channel', [$this, 'getChannel']), + new TwigFunction('get_channel_main_taxon', [$this, 'getChannelMainTaxon']), + ]; + } + + public function isPendingVendorProfileUpdate(): bool + { + $vendor = $this->vendorProvider->getVendor(); + $pendingUpdate = $this->manager->getRepository(ProfileUpdate::class) + ->findOneBy(['vendor' => $vendor]); + + if (null === $pendingUpdate) { + return true; + } + + return false; + } + + public function hasVirtualWalletStrategy(): bool + { + $vendor = $this->vendorProvider->getVendor(); + + return !in_array($vendor->getSettlementFrequency(), VendorSettlementFrequency::CYCLICAL_SETTLEMENT_FREQUENCIES, true); + } + + public function currentLocale(): string + { + return $this->localeContext->getLocaleCode(); + } + + public function getChannel(string $channelCode): ChannelInterface + { + /** @var ChannelInterface $channel */ + $channel = $this->channelRepository->findOneByCode($channelCode); + + return $channel; + } + + public function getChannelMainTaxon(): ?TaxonInterface + { + /** @var ChannelInterface $channel */ + $channel = $this->channelContext->getChannel(); + + return $channel->getMenuTaxon(); + } +} diff --git a/OpenMarketplace/src/Component/Messaging/Entity/Category.php b/OpenMarketplace/src/Component/Messaging/Entity/Category.php new file mode 100755 index 0000000..5ad91be --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Entity/Category.php @@ -0,0 +1,34 @@ +id; + } + + public function getName(): string + { + return $this->name; + } + + public function setName(string $name): void + { + $this->name = $name; + } +} diff --git a/OpenMarketplace/src/Component/Messaging/Entity/CategoryInterface.php b/OpenMarketplace/src/Component/Messaging/Entity/CategoryInterface.php new file mode 100755 index 0000000..9ed54e9 --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Entity/CategoryInterface.php @@ -0,0 +1,21 @@ + */ + protected ?Collection $messages = null; + + protected string $status = self::STATUS_OPEN; + + public function __construct() + { + $this->messages = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function getCategory(): ?CategoryInterface + { + return $this->category; + } + + public function setCategory(?CategoryInterface $category): void + { + $this->category = $category; + } + + public function addMessage(MessageInterface $message): void + { + if (null == $this->messages) { + $this->messages = new ArrayCollection(); + } + $this->messages->add($message); + $message->setConversation($this); + } + + public function removeMessage(MessageInterface $message): void + { + if (null !== $this->messages) { + $this->messages->removeElement($message); + } + } + + /** @return ?Collection */ + public function getMessages(): ?Collection + { + return $this->messages; + } + + public function getStatus(): string + { + return $this->status; + } + + public function setStatus(string $status): void + { + $this->status = $status; + } + + /** @param ?Collection $messages */ + public function setMessages(?Collection $messages): void + { + $this->messages = $messages; + } + + public function getShopUser(): ?ShopUserInterface + { + return $this->shopUser; + } + + public function setShopUser(?ShopUserInterface $shopUser): void + { + $this->shopUser = $shopUser; + } + + public function isClosed(): bool + { + return self::STATUS_CLOSED === $this->status; + } + + public function isOpen(): bool + { + return !$this->isClosed(); + } + + public function getRejectedListingURL(): ?string + { + return $this->rejectedListingURL; + } + + public function setRejectedListingURL(?string $rejectedListingURL): void + { + $this->rejectedListingURL = $rejectedListingURL; + } + + public function getApplicant(): ?ShopUserInterface + { + return $this->shopUser; + } + + public function isConversationReportedToArchive(): bool + { + if (null === $this->getMessages()) { + return false; + } + + foreach ($this->getMessages() as $message) { + if (MessagesStorage::ARCHIVE_REQUEST_MESSAGE === $message->getContent()) { + return true; + } + } + + return false; + } +} diff --git a/OpenMarketplace/src/Component/Messaging/Entity/ConversationInterface.php b/OpenMarketplace/src/Component/Messaging/Entity/ConversationInterface.php new file mode 100755 index 0000000..2b2f65d --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Entity/ConversationInterface.php @@ -0,0 +1,53 @@ + */ + public function getMessages(): ?Collection; + + /** @param ?Collection $messages */ + public function setMessages(?Collection $messages): void; + + public function getStatus(): string; + + public function setStatus(string $status): void; + + public function isClosed(): bool; + + public function isOpen(): bool; + + public function getRejectedListingURL(): ?string; + + public function setRejectedListingURL(?string $rejectedListingURL): void; + + public function getApplicant(): ?ShopUserInterface; + + public function isConversationReportedToArchive(): bool; +} diff --git a/OpenMarketplace/src/Component/Messaging/Entity/Message.php b/OpenMarketplace/src/Component/Messaging/Entity/Message.php new file mode 100755 index 0000000..ae7a1dc --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Entity/Message.php @@ -0,0 +1,153 @@ +id; + } + + public function getContent(): string + { + return $this->content; + } + + public function setContent(string $content): void + { + $this->content = $content; + } + + public function getCreatedAt(): \DateTimeInterface + { + return $this->createdAt; + } + + public function setCreatedAt(\DateTimeInterface $createdAt): void + { + $this->createdAt = $createdAt; + } + + public function getConversation(): ConversationInterface + { + return $this->conversation; + } + + public function setConversation(ConversationInterface $conversation): void + { + $this->conversation = $conversation; + } + + public function getFilename(): ?string + { + return $this->filename; + } + + public function setFilename(?string $filename): void + { + $this->filename = $filename; + } + + public function getAuthor(): ?UserInterface + { + $users = new ArrayCollection([ + $this->getAdminUser(), + $this->getShopUser(), + ]); + + foreach ($users as $user) { + if (null !== $user) { + return $user; + } + } + + return null; + } + + public function setAuthor(UserInterface $user): void + { + if ($user instanceof AdminUserInterface) { + $this->setAdminUser($user); + + return; + } + if ($user instanceof ShopUserInterface) { + $this->setShopUser($user); + } + } + + public function getShopUser(): ?ShopUserInterface + { + return $this->shopUser; + } + + public function setShopUser(?ShopUserInterface $shopUser): void + { + $this->shopUser = $shopUser; + } + + public function getVendorUser(): ?VendorInterface + { + return $this->vendorUser; + } + + public function setVendorUser(?VendorInterface $vendorUser): void + { + $this->vendorUser = $vendorUser; + } + + public function getAdminUser(): ?AdminUserInterface + { + return $this->adminUser; + } + + public function setAdminUser(?AdminUserInterface $adminUser): void + { + $this->adminUser = $adminUser; + } + + public function getFile(): ?UploadedFile + { + return $this->file; + } + + public function setFile(?UploadedFile $file): void + { + $this->file = $file; + } +} diff --git a/OpenMarketplace/src/Component/Messaging/Entity/MessageInterface.php b/OpenMarketplace/src/Component/Messaging/Entity/MessageInterface.php new file mode 100755 index 0000000..1c31a3c --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Entity/MessageInterface.php @@ -0,0 +1,58 @@ +setName($categoryName); + + return $category; + } +} diff --git a/OpenMarketplace/src/Component/Messaging/Factory/CategoryFactoryInterface.php b/OpenMarketplace/src/Component/Messaging/Factory/CategoryFactoryInterface.php new file mode 100755 index 0000000..5d3b28e --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Factory/CategoryFactoryInterface.php @@ -0,0 +1,22 @@ +conversationMessageFactory->createNew(); + + return $message; + } + + public function createNewWithArchiveRequest(): MessageInterface + { + $message = $this->createNew(); + $message->setContent(MessagesStorage::ARCHIVE_REQUEST_MESSAGE); + + return $message; + } +} diff --git a/OpenMarketplace/src/Component/Messaging/Factory/MessageFactoryInterface.php b/OpenMarketplace/src/Component/Messaging/Factory/MessageFactoryInterface.php new file mode 100755 index 0000000..36f7959 --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Factory/MessageFactoryInterface.php @@ -0,0 +1,20 @@ +currentUserResolver->resolve(); + + if (!$currentUser) { + throw new UserNotFoundException(); + } + + /** @var ConversationInterface $conversation */ + $conversation = $this->conversationRepository->find($conversationId); + + if ($file) { + $filename = $this->fileUploader->upload($file); + $message->setFilename($filename); + } + + if ($stripTags) { + $message->setContent(strip_tags($message->getContent())); + } + + $message->setAuthor($currentUser); + + $conversation->addMessage($message); + $this->conversationRepository->add($conversation); + } +} diff --git a/OpenMarketplace/src/Component/Messaging/MessagePersisterInterface.php b/OpenMarketplace/src/Component/Messaging/MessagePersisterInterface.php new file mode 100755 index 0000000..b8c3029 --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/MessagePersisterInterface.php @@ -0,0 +1,25 @@ +ARCHIVE_REQUEST_MESSAGE'; +} diff --git a/OpenMarketplace/src/Component/Messaging/Repository/CategoryRepository.php b/OpenMarketplace/src/Component/Messaging/Repository/CategoryRepository.php new file mode 100755 index 0000000..e00e0a0 --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Repository/CategoryRepository.php @@ -0,0 +1,18 @@ +createQueryBuilder('c'); + + $this->determineUserForQuery($query, $user); + + $query->andWhere('c.status = :status') + ->setParameter('status', $status); + + return $query->getQuery()->getResult(); + } + + private function determineUserForQuery(QueryBuilder $query, ?UserInterface $user): void + { + $expr = $query->expr(); + + if ($user instanceof VendorInterface) { + $query->andWhere($expr->eq('c.vendorUser', $user->getId())); + + return; + } + if ($user instanceof ShopUserInterface) { + $query->andWhere($expr->eq('c.shopUser', $user->getId())); + } + } +} diff --git a/OpenMarketplace/src/Component/Messaging/Repository/ConversationRepositoryInterface.php b/OpenMarketplace/src/Component/Messaging/Repository/ConversationRepositoryInterface.php new file mode 100755 index 0000000..fd194c3 --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Repository/ConversationRepositoryInterface.php @@ -0,0 +1,20 @@ + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Messaging/Resources/doctrine/Conversation.orm.xml b/OpenMarketplace/src/Component/Messaging/Resources/doctrine/Conversation.orm.xml new file mode 100755 index 0000000..92656ab --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Resources/doctrine/Conversation.orm.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Messaging/Resources/doctrine/Message.orm.xml b/OpenMarketplace/src/Component/Messaging/Resources/doctrine/Message.orm.xml new file mode 100755 index 0000000..1e85594 --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Resources/doctrine/Message.orm.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Messaging/Resources/parameters.yaml b/OpenMarketplace/src/Component/Messaging/Resources/parameters.yaml new file mode 100644 index 0000000..4db95ce --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Resources/parameters.yaml @@ -0,0 +1,12 @@ +parameters: + bitbag.open_marketplace.component.messaging.message.not_allowed_mime_types: + - application/x-msdownload + - application/x-shockwave-flash + - application/x-sh + - application/x-python + - application/x-ruby + - application/bat + - application/php + - application/javascript + - text/x-php + - text/html diff --git a/OpenMarketplace/src/Component/Messaging/Resources/services.xml b/OpenMarketplace/src/Component/Messaging/Resources/services.xml new file mode 100644 index 0000000..27c31f5 --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Resources/services.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Messaging/Resources/services/factories.xml b/OpenMarketplace/src/Component/Messaging/Resources/services/factories.xml new file mode 100644 index 0000000..fba9757 --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Resources/services/factories.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Messaging/Resources/services/uploaders.xml b/OpenMarketplace/src/Component/Messaging/Resources/services/uploaders.xml new file mode 100644 index 0000000..2fdbaaa --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Resources/services/uploaders.xml @@ -0,0 +1,13 @@ + + + + + + + + %env(MESSAGES_FILE_UPLOAD_DIRECTORY)% + + + diff --git a/OpenMarketplace/src/Component/Messaging/Resources/services/validators.xml b/OpenMarketplace/src/Component/Messaging/Resources/services/validators.xml new file mode 100644 index 0000000..272a1b9 --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Resources/services/validators.xml @@ -0,0 +1,14 @@ + + + + + + + + %bitbag.open_marketplace.component.messaging.message.not_allowed_mime_types% + + + + diff --git a/OpenMarketplace/src/Component/Messaging/Resources/validation/category.xml b/OpenMarketplace/src/Component/Messaging/Resources/validation/category.xml new file mode 100644 index 0000000..f9f68d3 --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Resources/validation/category.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Messaging/Resources/validation/conversation.xml b/OpenMarketplace/src/Component/Messaging/Resources/validation/conversation.xml new file mode 100644 index 0000000..886a861 --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Resources/validation/conversation.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Messaging/Resources/validation/message.xml b/OpenMarketplace/src/Component/Messaging/Resources/validation/message.xml new file mode 100644 index 0000000..1c77b85 --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Resources/validation/message.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Messaging/Uploader/AttachmentUploader.php b/OpenMarketplace/src/Component/Messaging/Uploader/AttachmentUploader.php new file mode 100644 index 0000000..d260e87 --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Uploader/AttachmentUploader.php @@ -0,0 +1,46 @@ +guessExtension(); + if (!file_exists($this->getTargetDirectory() . $filename)) { + break; + } + } + + try { + $file->move($this->getTargetDirectory(), $filename); + } catch (FileException $e) { + throw new FileException(); + } + + return $filename; + } + + public function getTargetDirectory(): string + { + return $this->targetDirectory; + } +} diff --git a/OpenMarketplace/src/Component/Messaging/Uploader/AttachmentUploaderInterface.php b/OpenMarketplace/src/Component/Messaging/Uploader/AttachmentUploaderInterface.php new file mode 100644 index 0000000..3f1015f --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Uploader/AttachmentUploaderInterface.php @@ -0,0 +1,19 @@ +service; + } +} diff --git a/OpenMarketplace/src/Component/Messaging/Validator/MessageFileMimeTypeValidator.php b/OpenMarketplace/src/Component/Messaging/Validator/MessageFileMimeTypeValidator.php new file mode 100644 index 0000000..39b7d30 --- /dev/null +++ b/OpenMarketplace/src/Component/Messaging/Validator/MessageFileMimeTypeValidator.php @@ -0,0 +1,63 @@ +getPathname() : (string) $value; + + if ($value instanceof File) { + $mime = $value->getMimeType(); + } elseif (class_exists(MimeTypes::class)) { + $mime = MimeTypes::getDefault()->guessMimeType($path); + } elseif (!class_exists(File::class)) { + throw new LogicException('You cannot validate the mime-type of files as the Mime component is not installed. Try running "composer require symfony/mime".'); + } else { + $mime = (new File($value))->getMimeType(); + } + + foreach ($this->notAllowedMimeTypes as $mimeType) { + if ($mimeType === $mime) { + $this->context->addViolation( + $constraint->message, + [ + '{{ type }}' => $this->formatValue($mime), + ] + ); + + return; + } + } + } +} diff --git a/OpenMarketplace/src/Component/Order/Calculator/ShipmentUnitsRecalculator.php b/OpenMarketplace/src/Component/Order/Calculator/ShipmentUnitsRecalculator.php new file mode 100644 index 0000000..eee5e8b --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Calculator/ShipmentUnitsRecalculator.php @@ -0,0 +1,39 @@ +getShipments() as $shipment) { + foreach ($shipment->getUnits() as $unit) { + $shipment->removeUnit($unit); + } + } + + foreach ($order->getItemUnits() as $itemUnit) { + /** @var OrderItemInterface $orderItem */ + $orderItem = $itemUnit->getOrderItem(); + /** @var ProductInterface $product */ + $product = $orderItem->getVariant()?->getProduct(); + if (null === $itemUnit->getShipment()) { + $shipment = $order->getShipmentByVendor($product->getVendor()); + $shipment?->addUnit($itemUnit); + } + } + } +} diff --git a/OpenMarketplace/src/Component/Order/Calculator/ShipmentUnitsRecalculatorInterface.php b/OpenMarketplace/src/Component/Order/Calculator/ShipmentUnitsRecalculatorInterface.php new file mode 100644 index 0000000..1bf789e --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Calculator/ShipmentUnitsRecalculatorInterface.php @@ -0,0 +1,19 @@ +setCreatedAt($originalAddress->getCreatedAt()); + $newAddress->setFirstName($originalAddress->getFirstName()); + $newAddress->setLastName($originalAddress->getLastName()); + $newAddress->setCity($originalAddress->getCity()); + $newAddress->setStreet($originalAddress->getStreet()); + $newAddress->setCompany($originalAddress->getCompany()); + $newAddress->setPostcode($originalAddress->getPostcode()); + $newAddress->setCountryCode($originalAddress->getCountryCode()); + $newAddress->setProvinceCode($originalAddress->getProvinceCode()); + $newAddress->setProvinceName($originalAddress->getProvinceName()); + } +} diff --git a/OpenMarketplace/src/Component/Order/Cloner/AddressClonerInterface.php b/OpenMarketplace/src/Component/Order/Cloner/AddressClonerInterface.php new file mode 100644 index 0000000..d628461 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Cloner/AddressClonerInterface.php @@ -0,0 +1,19 @@ +setType($originalAdjustment->getType()); + $newAdjustment->setOriginCode($originalAdjustment->getOriginCode()); + $newAdjustment->setNeutral($originalAdjustment->isNeutral()); + $newAdjustment->setLabel($originalAdjustment->getLabel()); + $newAdjustment->setDetails($originalAdjustment->getDetails()); + $newAdjustment->setAmount($originalAdjustment->getAmount()); + $newAdjustment->setCreatedAt($originalAdjustment->getCreatedAt()); + $newAdjustment->setUpdatedAt($originalAdjustment->getUpdatedAt()); + } +} diff --git a/OpenMarketplace/src/Component/Order/Cloner/AdjustmentClonerInterface.php b/OpenMarketplace/src/Component/Order/Cloner/AdjustmentClonerInterface.php new file mode 100644 index 0000000..68b4ea6 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Cloner/AdjustmentClonerInterface.php @@ -0,0 +1,19 @@ +getBillingAddress(); + /** @var AddressInterface $originalShippingAddress */ + $originalShippingAddress = $originalOrder->getShippingAddress(); + + $this->addressCloner->clone($originalBillingAddress, $newBillingAddress); + $this->addressCloner->clone($originalShippingAddress, $newShippingAddress); + + $this->entityManager->persist($newShippingAddress); + $this->entityManager->persist($newBillingAddress); + + $newOrder->setBillingAddress($newBillingAddress); + $newOrder->setShippingAddress($newShippingAddress); + $newOrder->setLocaleCode($originalOrder->getLocaleCode()); + $newOrder->setChannel($originalOrder->getChannel()); + $newOrder->setCheckoutCompletedAt($originalOrder->getCheckoutCompletedAt()); + $newOrder->setCurrencyCode($originalOrder->getCurrencyCode()); + $newOrder->setCustomerIp($originalOrder->getCustomerIp()); + $newOrder->setCreatedByGuest($originalOrder->getCreatedByGuest()); + $newOrder->setNotes($originalOrder->getNotes()); + $newOrder->setCreatedAt($originalOrder->getCreatedAt()); + $newOrder->setState($originalOrder->getState()); + $newOrder->setCheckoutState($originalOrder->getCheckoutState()); + $newOrder->setPaymentState($originalOrder->getPaymentState()); + $newOrder->setShippingState($originalOrder->getShippingState()); + $newOrder->setCustomer($originalOrder->getCustomer()); + + $payments = $originalOrder->getPayments(); + /** @var Payment $payment */ + foreach ($payments as $payment) { + $newPayment = new Payment(); + $this->paymentCloner->clone($payment, $newPayment); + $newOrder->addPayment($newPayment); + } + + $this->entityManager->flush(); + } +} diff --git a/OpenMarketplace/src/Component/Order/Cloner/OrderClonerInterface.php b/OpenMarketplace/src/Component/Order/Cloner/OrderClonerInterface.php new file mode 100644 index 0000000..71b586b --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Cloner/OrderClonerInterface.php @@ -0,0 +1,19 @@ +setOriginalUnitPrice($originalItem->getOriginalUnitPrice()); + $newItem->setProductName($originalItem->getProductName()); + $newItem->setVariant($originalItem->getVariant()); + $newItem->setVariantName($originalItem->getVariantName()); + $newItem->setUnitPrice($originalItem->getUnitPrice()); + $newItem->setVersion($originalItem->getVersion()); + $units = $originalItem->getUnits(); + + /** @var OrderItemUnit $unit */ + foreach ($units as $unit) { + $newUnit = new OrderItemUnit($newItem); + $this->itemUnitCloner->clone($unit, $newUnit); + $newUnit->setShipment($shipment); + $this->entityManager->persist($newUnit); + $newItem->addUnit($newUnit); + } + + $adjustments = $originalItem->getAdjustments(); + + /** @var AdjustmentInterface $adjustment */ + foreach ($adjustments as $adjustment) { + $newAdjustment = new Adjustment(); + $this->cloner->clone($adjustment, $newAdjustment); + $this->entityManager->persist($newAdjustment); + $newItem->addAdjustment($newAdjustment); + } + } +} diff --git a/OpenMarketplace/src/Component/Order/Cloner/OrderItemClonerInterface.php b/OpenMarketplace/src/Component/Order/Cloner/OrderItemClonerInterface.php new file mode 100644 index 0000000..4db1a2d --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Cloner/OrderItemClonerInterface.php @@ -0,0 +1,24 @@ +setUpdatedAt($originalUnit->getUpdatedAt()); + $newUnit->setCreatedAt($originalUnit->getCreatedAt()); + + $adjustments = $originalUnit->getAdjustments(); + + /** @var AdjustmentInterface $adjustment */ + foreach ($adjustments as $adjustment) { + $newAdjustment = new Adjustment(); + $this->cloner->clone($adjustment, $newAdjustment); + $newUnit->addAdjustment($newAdjustment); + + $this->entityManager->persist($newAdjustment); + } + } +} diff --git a/OpenMarketplace/src/Component/Order/Cloner/OrderItemUnitClonerInterface.php b/OpenMarketplace/src/Component/Order/Cloner/OrderItemUnitClonerInterface.php new file mode 100644 index 0000000..b4de732 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Cloner/OrderItemUnitClonerInterface.php @@ -0,0 +1,19 @@ +setCreatedAt($originalPayment->getCreatedAt()); + + if (null !== $originalPayment->getCurrencyCode()) { + $newPayment->setCurrencyCode($originalPayment->getCurrencyCode()); + } + $newPayment->setMethod($originalPayment->getMethod()); + $newPayment->setDetails($originalPayment->getDetails()); + if (null !== $originalPayment->getState()) { + $newPayment->setState($originalPayment->getState()); + } + $newPayment->setUpdatedAt($originalPayment->getUpdatedAt()); + } +} diff --git a/OpenMarketplace/src/Component/Order/Cloner/PaymentClonerInterface.php b/OpenMarketplace/src/Component/Order/Cloner/PaymentClonerInterface.php new file mode 100644 index 0000000..e986b2a --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Cloner/PaymentClonerInterface.php @@ -0,0 +1,19 @@ +setState($originalShipment->getState()); + $newShipment->setUpdatedAt($originalShipment->getUpdatedAt()); + $newShipment->setCreatedAt($originalShipment->getCreatedAt()); + $newShipment->setMethod($originalShipment->getMethod()); + + $adjustments = $originalShipment->getAdjustments(); + + /** @var AdjustmentInterface $adjustment */ + foreach ($adjustments as $adjustment) { + $newAdjustment = new Adjustment(); + $this->adjustmentCloner->clone($adjustment, $newAdjustment); + $newShipment->addAdjustment($newAdjustment); + } + } +} diff --git a/OpenMarketplace/src/Component/Order/Cloner/ShipmentClonerInterface.php b/OpenMarketplace/src/Component/Order/Cloner/ShipmentClonerInterface.php new file mode 100644 index 0000000..fea3554 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Cloner/ShipmentClonerInterface.php @@ -0,0 +1,19 @@ +isPrimary()) { + throw new \Exception('Primary order used for commission calculation'); + } + + return null === $order->getVendor(); + } + + public static function getDefaultPriority(): int + { + return 2; + } +} diff --git a/OpenMarketplace/src/Component/Order/CommissionCalculator/VendorCommissionCalculatorInterface.php b/OpenMarketplace/src/Component/Order/CommissionCalculator/VendorCommissionCalculatorInterface.php new file mode 100644 index 0000000..dfce155 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/CommissionCalculator/VendorCommissionCalculatorInterface.php @@ -0,0 +1,21 @@ +isPrimary()) { + throw new \Exception('Primary order cannot be used for gross commission'); + } + + /** @var VendorInterface $vendor */ + $vendor = $order->getVendor(); + + /** @var int $commission */ + $commission = $vendor->getCommission(); + + $floatTotal = $order->getTotal() / 100; + + $floatCommission = round(($floatTotal * ($commission / 100)), 2); + $intCommission = $floatCommission * 100; + + return (int) $intCommission; + } + + public function supports(OrderInterface $order): bool + { + /** @var VendorInterface $vendor */ + $vendor = $order->getVendor(); + + return VendorInterface::GROSS_COMMISSION === $vendor->getCommissionType(); + } + + public static function getDefaultPriority(): int + { + return 1; + } +} diff --git a/OpenMarketplace/src/Component/Order/CommissionCalculator/VendorNetCommissionCalculator.php b/OpenMarketplace/src/Component/Order/CommissionCalculator/VendorNetCommissionCalculator.php new file mode 100644 index 0000000..c0317f1 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/CommissionCalculator/VendorNetCommissionCalculator.php @@ -0,0 +1,51 @@ +isPrimary()) { + throw new \Exception('Primary order cannot be used for net commission'); + } + + /** @var VendorInterface $vendor */ + $vendor = $order->getVendor(); + + /** @var int $commission */ + $commission = $vendor->getCommission(); + + $floatTotal = $order->getItemsTotal() / 100; + + $floatCommission = round(($floatTotal * ($commission / 100)), 2); + $intCommission = $floatCommission * 100; + + return (int) $intCommission; + } + + public function supports(OrderInterface $order): bool + { + /** @var VendorInterface $vendor */ + $vendor = $order->getVendor(); + + return VendorInterface::NET_COMMISSION === $vendor->getCommissionType(); + } + + public static function getDefaultPriority(): int + { + return 1; + } +} diff --git a/OpenMarketplace/src/Component/Order/Entity/Order.php b/OpenMarketplace/src/Component/Order/Entity/Order.php new file mode 100644 index 0000000..0d5d74d --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Entity/Order.php @@ -0,0 +1,19 @@ + */ + public function getSecondaryOrders(): Collection; + + public function hasVendorShipment(?VendorInterface $vendor): bool; + + public function getVendorsFromOrderItems(): array; + + public function getShipmentByVendor(?VendorInterface $vendor): ?ShipmentInterface; + + public function getShipmentWithoutVendor(): ?ShipmentInterface; + + public function hasShippableItemsWithVendor(?VendorInterface $vendor): bool; + + public function getMode(): string; + + public function setMode(string $mode): void; + + public function isPrimary(): bool; + + public function getCommissionTotal(): int; + + public function setCommissionTotal(int $commissionTotal): void; + + public function getPaidAt(): ?\DateTimeInterface; + + public function setPaidAt(?\DateTimeInterface $paidAt): void; + + public function getTotalProfitAmount(): int; +} diff --git a/OpenMarketplace/src/Component/Order/Entity/OrderItem.php b/OpenMarketplace/src/Component/Order/Entity/OrderItem.php new file mode 100644 index 0000000..7055cd3 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Entity/OrderItem.php @@ -0,0 +1,19 @@ +getProduct(); + /** @var VendorInterface $vendor */ + $vendor = $product->getVendor(); + + return $vendor; + } +} diff --git a/OpenMarketplace/src/Component/Order/Entity/OrderTrait.php b/OpenMarketplace/src/Component/Order/Entity/OrderTrait.php new file mode 100644 index 0000000..e0deb67 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Entity/OrderTrait.php @@ -0,0 +1,193 @@ + */ + protected $items; + + protected ?VendorInterface $vendor = null; + + protected ?OrderInterface $primaryOrder = null; + + /** @var Collection */ + protected Collection $secondaryOrders; + + protected int $commissionTotal = 0; + + protected string $mode = self::PRIMARY_ORDER_MODE; + + protected ?\DateTimeInterface $paidAt = null; + + public function __construct() + { + parent::__construct(); + $this->secondaryOrders = new ArrayCollection(); + } + + public function getVendor(): ?VendorInterface + { + return $this->vendor; + } + + public function setVendor(?VendorInterface $vendor): void + { + $this->vendor = $vendor; + } + + public function getPrimaryOrder(): ?OrderInterface + { + return $this->primaryOrder; + } + + public function setPrimaryOrder(?OrderInterface $primaryOrder): void + { + $this->primaryOrder = $primaryOrder; + } + + public function addSecondaryOrder(OrderInterface $secondaryOrder): void + { + $this->secondaryOrders->add($secondaryOrder); + } + + /** @return Collection */ + public function getSecondaryOrders(): Collection + { + return $this->secondaryOrders; + } + + public function hasVendorShipment(?VendorInterface $vendor): bool + { + /** @var ShipmentInterface $shipment */ + foreach ($this->getShipments() as $shipment) { + if ($shipment->getVendor() === $vendor) { + return true; + } + } + + return false; + } + + public function getVendorsFromOrderItems(): array + { + $vendors = []; + + foreach ($this->getItems() as $item) { + /** @var ProductInterface $product */ + /** @phpstan-ignore-next-line */ + $product = $item->getVariant()?->getProduct(); + $vendor = $product->getVendor(); + + if (false === in_array($vendor, $vendors)) { + $vendors[] = $vendor; + } + } + + return $vendors; + } + + public function getShipmentByVendor(?VendorInterface $vendor): ?ShipmentInterface + { + /** @var ShipmentInterface $shipment */ + foreach ($this->getShipments() as $shipment) { + if ($shipment->getVendor() === $vendor) { + return $shipment; + } + } + + return null; + } + + public function getShipmentWithoutVendor(): ?ShipmentInterface + { + return $this->getShipmentByVendor(null); + } + + public function hasShippableItemsWithVendor(?VendorInterface $vendor): bool + { + /** @var OrderItem $item */ + foreach ($this->getItems() as $item) { + /** @var ProductInterface $product */ + $product = $item->getProduct(); + + /** @var ProductVariantInterface $variant */ + $variant = $item->getVariant(); + + if ($vendor === $product->getVendor() && true === $variant->isShippingRequired()) { + return true; + } + } + + return false; + } + + public function getMode(): string + { + return $this->mode; + } + + public function setMode(string $mode): void + { + $this->mode = $mode; + } + + public function isPrimary(): bool + { + return self::PRIMARY_ORDER_MODE === $this->getMode(); + } + + public function getSecondaryPayments(): Collection + { + $payments = new ArrayCollection(); + $secondaryOrders = $this->getSecondaryOrders(); + if (0 === $secondaryOrders->count()) { + return $payments; + } + + foreach ($secondaryOrders as $order) { + $payments->add($order->getPayments()->first()); + } + + return $payments; + } + + public function getCommissionTotal(): int + { + return $this->commissionTotal; + } + + public function setCommissionTotal(int $commissionTotal): void + { + $this->commissionTotal = $commissionTotal; + } + + public function getPaidAt(): ?\DateTimeInterface + { + return $this->paidAt; + } + + public function setPaidAt(?\DateTimeInterface $paidAt): void + { + $this->paidAt = $paidAt; + } + + public function getTotalProfitAmount(): int + { + return $this->getTotal() - $this->getCommissionTotal(); + } +} diff --git a/OpenMarketplace/src/Component/Order/Entity/Shipment.php b/OpenMarketplace/src/Component/Order/Entity/Shipment.php new file mode 100644 index 0000000..e49c5de --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Entity/Shipment.php @@ -0,0 +1,19 @@ +vendor); + } + + public function getVendor(): ?VendorInterface + { + return $this->vendor; + } + + public function setVendor(?VendorInterface $vendor): void + { + $this->vendor = $vendor; + } +} diff --git a/OpenMarketplace/src/Component/Order/Event/PostSplitOrderEvent.php b/OpenMarketplace/src/Component/Order/Event/PostSplitOrderEvent.php new file mode 100644 index 0000000..3a5a164 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Event/PostSplitOrderEvent.php @@ -0,0 +1,35 @@ +orders = $orders; + } + + public function getOrders(): array + { + return $this->orders; + } +} diff --git a/OpenMarketplace/src/Component/Order/Event/PreSplitOrderEvent.php b/OpenMarketplace/src/Component/Order/Event/PreSplitOrderEvent.php new file mode 100644 index 0000000..19a0886 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Event/PreSplitOrderEvent.php @@ -0,0 +1,31 @@ +order = $order; + } + + public function getOrder(): OrderInterface + { + return $this->order; + } +} diff --git a/OpenMarketplace/src/Component/Order/EventListener/CalculateOrderCommissionListener.php b/OpenMarketplace/src/Component/Order/EventListener/CalculateOrderCommissionListener.php new file mode 100644 index 0000000..d601b36 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/EventListener/CalculateOrderCommissionListener.php @@ -0,0 +1,49 @@ +commissionCalculators = $commissionCalculators; + $this->entityManager = $entityManager; + } + + public function calculate(PostSplitOrderEvent $event): void + { + foreach ($event->getOrders() as $order) { + $commission = $this->calculateCommission($order); + $order->setCommissionTotal($commission); + $this->entityManager->persist($order); + } + } + + private function calculateCommission(OrderInterface $order): int + { + foreach ($this->commissionCalculators as $commissionCalculator) { + if ($commissionCalculator->supports($order)) { + return $commissionCalculator->calculate($order); + } + } + + throw new \RuntimeException('No commission calculator found for order'); + } +} diff --git a/OpenMarketplace/src/Component/Order/Factory/OrderFactory.php b/OpenMarketplace/src/Component/Order/Factory/OrderFactory.php new file mode 100644 index 0000000..04a0a95 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Factory/OrderFactory.php @@ -0,0 +1,28 @@ +orderFQN(); + } +} diff --git a/OpenMarketplace/src/Component/Order/Factory/OrderFactoryInterface.php b/OpenMarketplace/src/Component/Order/Factory/OrderFactoryInterface.php new file mode 100644 index 0000000..2f6d972 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Factory/OrderFactoryInterface.php @@ -0,0 +1,19 @@ +orderItemFQN(); + } +} diff --git a/OpenMarketplace/src/Component/Order/Factory/OrderItemFactoryInterface.php b/OpenMarketplace/src/Component/Order/Factory/OrderItemFactoryInterface.php new file mode 100644 index 0000000..5193cb3 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Factory/OrderItemFactoryInterface.php @@ -0,0 +1,19 @@ +shipmentFQN(); + } + + public function createNewWithOrder(OrderInterface $order): ShipmentInterface + { + $shipment = $this->createNew(); + $shipment->setOrder($order); + + return $shipment; + } + + public function tryCreateNewWithOrderVendorAndDefaultShipment( + OrderInterface $order, + ?VendorInterface $vendor, + ): ?ShipmentInterface { + $shipment = $this->createNewWithOrder($order); + + try { + if (null !== $vendor) { + $shipment->setVendor($vendor); + + $defaultVendorShippingMethod = $this + ->defaultVendorShippingMethodResolver + ->getDefaultShippingMethod($vendor, $order->getChannel()); + $defaultShippingMethod = $defaultVendorShippingMethod->getShippingMethod(); + } else { + $defaultShippingMethod = $this->defaultShippingMethodResolver->getDefaultShippingMethod($shipment); + } + + $shipment->setMethod($defaultShippingMethod); + + return $shipment; + } catch (UnresolvedDefaultShippingMethodException) { + return null; + } + } +} diff --git a/OpenMarketplace/src/Component/Order/Factory/ShipmentFactoryInterface.php b/OpenMarketplace/src/Component/Order/Factory/ShipmentFactoryInterface.php new file mode 100644 index 0000000..2e68001 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Factory/ShipmentFactoryInterface.php @@ -0,0 +1,28 @@ +factory->createNew(); + $this->cloner->clone($order, $newOrder); + + $newOrder->setVendor($itemVendor); + $newOrder->setPrimaryOrder($order); + $newOrder->setMode(OrderInterface::SECONDARY_ORDER_MODE); + + $this->entityManager->persist($newOrder); + $this->entityManager->flush(); + + $shipment = $order->getShipmentByVendor($itemVendor); + $newShipment = null; + + if (null !== $shipment) { + $newShipment = $this->shipmentFactory->createNew(); + $newShipment->setOrder($newOrder); + $this->shipmentCloner->clone($shipment, $newShipment); + $newOrder->addShipment($newShipment); + $this->entityManager->persist($newShipment); + } + + $this->cloneItemIntoSecondaryOrder($item, $newOrder, $newShipment); + + return $newOrder; + } + + public function addItemIntoSecondaryOrder( + array $secondaryOrders, + ?VendorInterface $itemVendor, + OrderItemInterface $item + ): void { + /** @var OrderInterface $secondaryOrder */ + $secondaryOrder = $this->getVendorSecondaryOrder($secondaryOrders, $itemVendor); + /** @var ShipmentInterface $shipment */ + $shipment = $secondaryOrder->getShipments()[0]; + $this->cloneItemIntoSecondaryOrder($item, $secondaryOrder, $shipment); + } + + private function getVendorSecondaryOrder( + array $secondaryOrders, + ?VendorInterface $vendor + ): ?OrderInterface { + foreach ($secondaryOrders as $secondaryOrder) { + if ($secondaryOrder->getVendor() === $vendor) { + return $secondaryOrder; + } + } + + return null; + } + + private function cloneItemIntoSecondaryOrder( + OrderItemInterface $item, + OrderInterface $order, + ?ShipmentInterface $shipment + ): void { + $newItem = $this->itemFactory->createNew(); + $this->orderItemCloner->clone($item, $newItem, $shipment); + $order->addItem($newItem); + } +} diff --git a/OpenMarketplace/src/Component/Order/OrderManagerInterface.php b/OpenMarketplace/src/Component/Order/OrderManagerInterface.php new file mode 100644 index 0000000..20b4403 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/OrderManagerInterface.php @@ -0,0 +1,31 @@ +isPrimary() && 0 < $order->getSecondaryOrders()->count(); + + if ($isPrimaryOrder) { + $orders = [$order, ...$order->getSecondaryOrders()]; + $this->refreshPayments($orders); + + return $orders; + } + + $this->eventDispatcher->dispatch(new PreSplitOrderEvent($order), PreSplitOrderEvent::NAME); + + $secondaryOrders = []; + + /** @var array $orderItems */ + $orderItems = $order->getItems(); + /** @var OrderItemInterface $item */ + foreach ($orderItems as $item) { + $itemVendor = $item->getProductOwner(); + if ($this->vendorSecondaryOrderExits($secondaryOrders, $itemVendor)) { + $this->orderManager->addItemIntoSecondaryOrder($secondaryOrders, $itemVendor, $item); + } else { + $secondaryOrders[] = $this->orderManager->generateNewSecondaryOrder($order, $itemVendor, $item); + } + } + + $this->eventDispatcher->dispatch(new PostSplitOrderEvent($secondaryOrders), PostSplitOrderEvent::NAME); + + $orders = [$order, ...$secondaryOrders]; + $this->refreshPayments($orders); + + return $orders; + } + + private function vendorSecondaryOrderExits(array $secondaryOrders, ?VendorInterface $vendor): bool + { + foreach ($secondaryOrders as $secondaryOrder) { + if ($secondaryOrder->getVendor() === $vendor) { + return true; + } + } + + return false; + } + + private function refreshPayments(array $orders): void + { + foreach ($orders as $order) { + $this->paymentRefresher->refreshPayment($order); + } + } +} diff --git a/OpenMarketplace/src/Component/Order/Processor/SplitOrderByVendorProcessorInterface.php b/OpenMarketplace/src/Component/Order/Processor/SplitOrderByVendorProcessorInterface.php new file mode 100644 index 0000000..2979e36 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Processor/SplitOrderByVendorProcessorInterface.php @@ -0,0 +1,19 @@ +entityManager = $entityManager; + } + + public function refreshPayment(OrderInterface $secondaryOrder): void + { + $secondaryOrder->recalculateItemsTotal(); + $secondaryOrder->recalculateAdjustmentsTotal(); + + $this->refreshPaymentMethodAndAmount($secondaryOrder); + + $this->entityManager->persist($secondaryOrder); + } + + private function refreshPaymentMethodAndAmount(OrderInterface $secondaryOrder): void + { + $secondaryOrderPayment = $secondaryOrder->getLastPayment(); + if (!$secondaryOrderPayment instanceof PaymentInterface) { + return; + } + + $secondaryOrderPayment->setAmount($secondaryOrder->getTotal()); + + $primaryOrder = $secondaryOrder->getPrimaryOrder(); + + if (!$primaryOrder instanceof OrderInterface) { + return; + } + + $primaryOrderPayment = $primaryOrder->getLastPayment(); + + if (!$primaryOrderPayment instanceof PaymentInterface) { + return; + } + + $secondaryOrderPayment->setMethod($primaryOrderPayment->getMethod()); + } +} diff --git a/OpenMarketplace/src/Component/Order/Refresher/PaymentRefresherInterface.php b/OpenMarketplace/src/Component/Order/Refresher/PaymentRefresherInterface.php new file mode 100644 index 0000000..d1de3b8 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Refresher/PaymentRefresherInterface.php @@ -0,0 +1,19 @@ +getId(); + + return $this->createQueryBuilder('o') + ->andWhere('o.vendor = :vendor') + ->setParameter('vendor', $vendorId) + ; + } + + public function findAllSecondaryOrdersQueryBuilder(): QueryBuilder + { + $queryBuilder = $this->createListQueryBuilder(); + $alias = $queryBuilder->getRootAliases()[0]; + + return $queryBuilder + ->andWhere(sprintf('%s.mode = :mode', $alias)) + ->setParameter('mode', OrderInterface::SECONDARY_ORDER_MODE) + ; + } + + public function findOrderForVendor(VendorInterface $vendor, string $id): ?OrderInterface + { + $vendorId = $vendor->getId(); + + return $this->createQueryBuilder('o') + ->andWhere('o.vendor = :vendor') + ->andWhere('o.id = :id') + ->setParameter('vendor', $vendorId) + ->setParameter('id', $id) + ->setMaxResults(1) + ->getQuery() + ->getOneOrNullResult(); + } + + public function findOrdersForVendorByCustomer(VendorInterface $vendor, string $id): QueryBuilder + { + $vendorId = $vendor->getId(); + + return $this->createQueryBuilder('o') + ->leftJoin('o.customer', 'c') + ->andWhere('o.vendor = :vendor') + ->andWhere('c.id = :id') + ->setParameter('vendor', $vendorId) + ->setParameter('id', $id); + } + + public function createByCustomerAndChannelIdAndSecondaryQueryBuilder(int $customerId, int $channelId): QueryBuilder + { + return $this->createQueryBuilder('o') + ->andWhere('o.customer = :customerId') + ->andWhere('o.channel = :channelId') + ->andWhere('o.state != :state') + ->andWhere('o.mode = :secondaryOrderMode') + ->setParameter('secondaryOrderMode', OrderInterface::SECONDARY_ORDER_MODE) + ->setParameter('customerId', $customerId) + ->setParameter('channelId', $channelId) + ->setParameter('state', OrderInterfaceAlias::STATE_CART) + ; + } + + public function getTotalPaidSalesForChannel(ChannelInterface $channel): int + { + return (int) $this->createQueryBuilder('o') + ->select('SUM(o.total)') + ->andWhere('o.channel = :channel') + ->andWhere('o.paymentState = :state') + ->andWhere('o.mode != :mode') + ->setParameter('channel', $channel) + ->setParameter('state', OrderPaymentStates::STATE_PAID) + ->setParameter('mode', OrderInterface::PRIMARY_ORDER_MODE) + ->getQuery() + ->getSingleScalarResult() + ; + } + + public function getTotalPaidSalesForChannelInPeriod( + ChannelInterface $channel, + \DateTimeInterface $startDate, + \DateTimeInterface $endDate, + ): int { + return (int) $this->createQueryBuilder('o') + ->select('SUM(o.total)') + ->andWhere('o.channel = :channel') + ->andWhere('o.paymentState = :state') + ->andWhere('o.checkoutCompletedAt >= :startDate') + ->andWhere('o.checkoutCompletedAt <= :endDate') + ->andWhere('o.mode != :mode') + ->setParameter('channel', $channel) + ->setParameter('state', OrderPaymentStates::STATE_PAID) + ->setParameter('startDate', $startDate) + ->setParameter('endDate', $endDate) + ->setParameter('mode', OrderInterface::PRIMARY_ORDER_MODE) + ->getQuery() + ->getSingleScalarResult() + ; + } + + public function countPaidByChannel(ChannelInterface $channel): int + { + return (int) $this->createQueryBuilder('o') + ->select('COUNT(o.id)') + ->andWhere('o.channel = :channel') + ->andWhere('o.paymentState = :state') + ->andWhere('o.mode != :mode') + ->setParameter('channel', $channel) + ->setParameter('state', OrderPaymentStates::STATE_PAID) + ->setParameter('mode', OrderInterface::PRIMARY_ORDER_MODE) + ->getQuery() + ->getSingleScalarResult() + ; + } + + public function countPaidForChannelInPeriod( + ChannelInterface $channel, + \DateTimeInterface $startDate, + \DateTimeInterface $endDate, + ): int { + return (int) $this->createQueryBuilder('o') + ->select('COUNT(o.id)') + ->andWhere('o.channel = :channel') + ->andWhere('o.paymentState = :state') + ->andWhere('o.checkoutCompletedAt >= :startDate') + ->andWhere('o.checkoutCompletedAt <= :endDate') + ->andWhere('o.mode != :mode') + ->setParameter('channel', $channel) + ->setParameter('state', OrderPaymentStates::STATE_PAID) + ->setParameter('startDate', $startDate) + ->setParameter('endDate', $endDate) + ->setParameter('mode', OrderInterface::PRIMARY_ORDER_MODE) + ->getQuery() + ->getSingleScalarResult() + ; + } + + public function findLatestInChannel(int $count, ChannelInterface $channel): array + { + return $this->createQueryBuilder('o') + ->andWhere('o.channel = :channel') + ->andWhere('o.state != :state') + ->andWhere('o.mode != :mode') + ->addOrderBy('o.checkoutCompletedAt', 'DESC') + ->setParameter('channel', $channel) + ->setParameter('state', \Sylius\Component\Core\Model\OrderInterface::STATE_CART) + ->setParameter('mode', OrderInterface::PRIMARY_ORDER_MODE) + ->setMaxResults($count) + ->getQuery() + ->getResult() + ; + } + + // PHPStan warns about no type specified for $customerId argument + // As method below overwrites another method, such type addition is not possible + /** @phpstan-ignore-next-line */ + public function createByCustomerIdQueryBuilder($customerId): QueryBuilder + { + return $this->createListQueryBuilder() + ->andWhere('o.customer = :customerId') + ->andWhere('o.mode != :mode') + ->setParameter('customerId', $customerId) + ->setParameter('mode', OrderInterface::PRIMARY_ORDER_MODE) + ; + } + + public function findForSettlementByVendorAndChannelAndDates( + VendorInterface $vendor, + ChannelInterface $channel, + \DateTimeInterface $nextSettlementStartDate, + \DateTimeInterface $nextSettlementEndDate + ): array { + $qb = $this->findAllByVendorQueryBuilder($vendor); + + return $qb + ->select('SUM(o.total) as total, SUM(o.commissionTotal) as commissionTotal') + ->andWhere('o.channel = :channel') + ->andWhere( + $qb->expr()->between( + 'o.paidAt', + ':startDate', + ':endDate' + ) + ) + ->setParameter('channel', $channel->getId()) + ->setParameter('startDate', $nextSettlementStartDate) + ->setParameter('endDate', $nextSettlementEndDate) + ->getQuery() + ->getSingleResult(); + } + + public function findForSettlementQueryBuilder(SettlementInterface $settlement): QueryBuilder + { + return $this->findAllByVendorQueryBuilder($settlement->getVendor()) + ->andWhere('o.mode = :secondaryOrderMode') + ->andWhere('o.channel = :channel') + ->andWhere('o.paidAt BETWEEN :startDate AND :endDate') + ->setParameter('secondaryOrderMode', OrderInterface::SECONDARY_ORDER_MODE) + ->setParameter('channel', $settlement->getChannel()) + ->setParameter('startDate', $settlement->getStartDate()) + ->setParameter('endDate', $settlement->getEndDate()) + ; + } + + public function countOrderForSettlement(SettlementInterface $settlement): int + { + return (int) $this->findForSettlementQueryBuilder($settlement) + ->select('COUNT(o.id)') + ->getQuery() + ->getSingleScalarResult() + ; + } +} diff --git a/OpenMarketplace/src/Component/Order/Repository/OrderRepositoryInterface.php b/OpenMarketplace/src/Component/Order/Repository/OrderRepositoryInterface.php new file mode 100644 index 0000000..645cc0f --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Repository/OrderRepositoryInterface.php @@ -0,0 +1,64 @@ +createListQueryBuilder(); + $alias = $queryBuilder->getRootAliases()[0]; + + return $queryBuilder + ->join(sprintf('%s.order', $alias), 'orderAlias') + ->andWhere('orderAlias.mode != :primaryMode') + ->setParameter('primaryMode', OrderInterface::PRIMARY_ORDER_MODE) + ; + } +} diff --git a/OpenMarketplace/src/Component/Order/Repository/ShipmentRepository.php b/OpenMarketplace/src/Component/Order/Repository/ShipmentRepository.php new file mode 100644 index 0000000..fa630cf --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Repository/ShipmentRepository.php @@ -0,0 +1,31 @@ +createListQueryBuilder(); + $alias = $queryBuilder->getRootAliases()[0]; + + return $queryBuilder + ->join(sprintf('%s.order', $alias), 'orderAlias') + ->andWhere('orderAlias.mode != :primaryMode') + ->setParameter('primaryMode', OrderInterface::PRIMARY_ORDER_MODE) + ; + } +} diff --git a/OpenMarketplace/src/Component/Order/Resolver/VendorShippingMethodsResolver.php b/OpenMarketplace/src/Component/Order/Resolver/VendorShippingMethodsResolver.php new file mode 100644 index 0000000..2bfe6eb --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Resolver/VendorShippingMethodsResolver.php @@ -0,0 +1,83 @@ +vendorShippingMethodRepository->findEnabledForChannel($vendor, $channel); + if (empty($shippingMethods)) { + throw new UnresolvedDefaultShippingMethodException(); + } + + return $shippingMethods[0]; + } + + /** + * @param ShipmentInterface $subject + */ + public function getSupportedMethods(ShippingSubjectInterface $subject): array + { + Assert::isInstanceOf($subject, ShipmentInterface::class); + Assert::true($this->supports($subject)); + + /** @var VendorInterface $vendor */ + $vendor = $subject->getVendor(); + /** @var ChannelInterface $channel */ + $channel = $subject->getOrder()?->getChannel(); + + $vendorShippingMethods = $this + ->vendorShippingMethodRepository + ->findEnabledForChannel($vendor, $channel) + ; + + $shippingMethods = []; + /** @var VendorShippingMethodInterface $vendorShippingMethod */ + foreach ($vendorShippingMethods as $vendorShippingMethod) { + /** @var ShippingMethodInterface $shippingMethod */ + $shippingMethod = $vendorShippingMethod->getShippingMethod(); + $shippingMethods[] = $shippingMethod; + } + + return $shippingMethods; + } + + public function supports(ShippingSubjectInterface $subject): bool + { + return $subject instanceof ShipmentInterface && + $subject->hasVendor() && + null !== $subject->getOrder() && + null !== $subject->getOrder()->getChannel(); + } +} diff --git a/OpenMarketplace/src/Component/Order/Resolver/VendorShippingMethodsResolverInterface.php b/OpenMarketplace/src/Component/Order/Resolver/VendorShippingMethodsResolverInterface.php new file mode 100644 index 0000000..0e980a9 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Resolver/VendorShippingMethodsResolverInterface.php @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Order/Resources/doctrine/OrderItem.orm.xml b/OpenMarketplace/src/Component/Order/Resources/doctrine/OrderItem.orm.xml new file mode 100644 index 0000000..d72e249 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Resources/doctrine/OrderItem.orm.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Order/Resources/doctrine/Shipment.orm.xml b/OpenMarketplace/src/Component/Order/Resources/doctrine/Shipment.orm.xml new file mode 100644 index 0000000..1f2ad48 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Resources/doctrine/Shipment.orm.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Order/Resources/services.xml b/OpenMarketplace/src/Component/Order/Resources/services.xml new file mode 100644 index 0000000..001564a --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Resources/services.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Order/Resources/services/calculators.xml b/OpenMarketplace/src/Component/Order/Resources/services/calculators.xml new file mode 100644 index 0000000..0c114df --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Resources/services/calculators.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Order/Resources/services/cloners.xml b/OpenMarketplace/src/Component/Order/Resources/services/cloners.xml new file mode 100644 index 0000000..f1776af --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Resources/services/cloners.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Order/Resources/services/event_listeners.xml b/OpenMarketplace/src/Component/Order/Resources/services/event_listeners.xml new file mode 100644 index 0000000..d64b01c --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Resources/services/event_listeners.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Order/Resources/services/factories.xml b/OpenMarketplace/src/Component/Order/Resources/services/factories.xml new file mode 100644 index 0000000..614911a --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Resources/services/factories.xml @@ -0,0 +1,25 @@ + + + + + + + + %sylius.model.order.class% + + + + %sylius.model.order_item.class% + + + + %sylius.model.shipment.class% + + + + + diff --git a/OpenMarketplace/src/Component/Order/Resources/services/processors.xml b/OpenMarketplace/src/Component/Order/Resources/services/processors.xml new file mode 100644 index 0000000..ca76cab --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Resources/services/processors.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Order/Resources/services/refreshers.xml b/OpenMarketplace/src/Component/Order/Resources/services/refreshers.xml new file mode 100644 index 0000000..6dfc1a9 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Resources/services/refreshers.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Order/Resources/services/resolvers.xml b/OpenMarketplace/src/Component/Order/Resources/services/resolvers.xml new file mode 100644 index 0000000..3ed2a29 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Resources/services/resolvers.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Order/Resources/services/state_machine.xml b/OpenMarketplace/src/Component/Order/Resources/services/state_machine.xml new file mode 100644 index 0000000..d5dec48 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/Resources/services/state_machine.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Order/StateMachine/OrderCallbacks.php b/OpenMarketplace/src/Component/Order/StateMachine/OrderCallbacks.php new file mode 100644 index 0000000..7610f31 --- /dev/null +++ b/OpenMarketplace/src/Component/Order/StateMachine/OrderCallbacks.php @@ -0,0 +1,34 @@ +setPaidAt(new \DateTime()); + $this->virtualWalletManager->stash($order); + + $this->objectManager->persist($order); + $this->objectManager->flush(); + } +} diff --git a/OpenMarketplace/src/Component/Override/Resources/config.yaml b/OpenMarketplace/src/Component/Override/Resources/config.yaml new file mode 100644 index 0000000..c66e4b9 --- /dev/null +++ b/OpenMarketplace/src/Component/Override/Resources/config.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: "state_machine/*.yaml" } diff --git a/OpenMarketplace/src/Component/Override/Resources/routing.yaml b/OpenMarketplace/src/Component/Override/Resources/routing.yaml new file mode 100644 index 0000000..f28db0c --- /dev/null +++ b/OpenMarketplace/src/Component/Override/Resources/routing.yaml @@ -0,0 +1,5 @@ +open_marketplace_shop_account: + resource: "routing/account.yaml" + +open_marketplace_shop_checkout: + resource: "routing/checkout.yaml" diff --git a/OpenMarketplace/src/Component/Override/Resources/routing/account.yaml b/OpenMarketplace/src/Component/Override/Resources/routing/account.yaml new file mode 100644 index 0000000..57359fc --- /dev/null +++ b/OpenMarketplace/src/Component/Override/Resources/routing/account.yaml @@ -0,0 +1,28 @@ +sylius_shop_account_order_index: + path: /{_locale}/account/orders + methods: [GET] + requirements: + _locale: ^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$ + defaults: + _controller: sylius.controller.order:indexAction + _sylius: + section: shop_account + template: "@SyliusShop/Account/Order/index.html.twig" + grid: open_marketplace_account_order + +sylius_shop_account_order_show: + path: /{_locale}/account/orders/{number} + methods: [GET] + requirements: + _locale: ^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$ + defaults: + _controller: sylius.controller.order:showAction + _sylius: + section: shop_account + template: "@SyliusShop/Account/Order/show.html.twig" + repository: + method: findOneByNumberAndCustomer + arguments: + - $number + - "expr:service('sylius.context.customer').getCustomer()" + diff --git a/OpenMarketplace/src/Component/Override/Resources/routing/checkout.yaml b/OpenMarketplace/src/Component/Override/Resources/routing/checkout.yaml new file mode 100644 index 0000000..bb7e910 --- /dev/null +++ b/OpenMarketplace/src/Component/Override/Resources/routing/checkout.yaml @@ -0,0 +1,56 @@ +sylius_shop_checkout_complete: + path: /{_locale}/checkout/complete + methods: [GET, PUT] + requirements: + _locale: ^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$ + defaults: + _controller: sylius.controller.order:updateAction + _sylius: + event: complete + flash: false + template: '@SyliusShop/Checkout/complete.html.twig' + repository: + method: find + arguments: + - "expr:service('sylius.context.cart').getCart()" + state_machine: + graph: sylius_order_checkout + transition: complete + redirect: + route: sylius_shop_order_pay + parameters: + tokenValue: resource.tokenValue + form: + type: Sylius\Bundle\CoreBundle\Form\Type\Checkout\CompleteType + options: + validation_groups: 'sylius_checkout_complete' + +sylius_shop_checkout_select_shipping: + path: /{_locale}/checkout/select-shipping + methods: [GET, PUT] + requirements: + _locale: ^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$ + defaults: + _controller: sylius.controller.order:updateAction + _sylius: + event: select_shipping + flash: false + template: "Context/Shop/Checkout/selectShipping.html.twig" + form: BitBag\OpenMarketplace\Component\Core\Shop\Form\Type\Checkout\SelectShippingType + repository: + method: findCartForSelectingShipping + arguments: + - "expr:service('sylius.context.cart').getCart().getId()" + state_machine: + graph: sylius_order_checkout + transition: select_shipping + +sylius_shop_order_thank_you: + path: /{_locale}/thank-you + methods: [GET] + requirements: + _locale: ^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$ + defaults: + _controller: sylius.controller.order:thankYouAction + _sylius: + template: "Context/Shop/Checkout/thankYou.html.twig" diff --git a/OpenMarketplace/src/Component/Override/Resources/services.xml b/OpenMarketplace/src/Component/Override/Resources/services.xml new file mode 100644 index 0000000..8f4f7b1 --- /dev/null +++ b/OpenMarketplace/src/Component/Override/Resources/services.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Override/Resources/state_machine/sylius_order_payment.yaml b/OpenMarketplace/src/Component/Override/Resources/state_machine/sylius_order_payment.yaml new file mode 100644 index 0000000..9858efc --- /dev/null +++ b/OpenMarketplace/src/Component/Override/Resources/state_machine/sylius_order_payment.yaml @@ -0,0 +1,58 @@ +winzou_state_machine: + sylius_order_payment: + class: "%sylius.model.order.class%" + property_path: paymentState + graph: sylius_order_payment + state_machine_class: "%sylius.state_machine.class%" + states: + cart: ~ + awaiting_payment: ~ + partially_authorized: ~ + authorized: ~ + partially_paid: ~ + cancelled: ~ + paid: ~ + partially_refunded: ~ + refunded: ~ + transitions: + request_payment: + from: [ cart ] + to: awaiting_payment + partially_authorize: + from: [ awaiting_payment, partially_authorized ] + to: partially_authorized + authorize: + from: [ awaiting_payment, partially_authorized ] + to: authorized + partially_pay: + from: [ awaiting_payment, partially_paid, partially_authorized ] + to: partially_paid + cancel: + from: [ awaiting_payment, authorized, partially_authorized ] + to: cancelled + pay: + from: [ awaiting_payment, partially_paid, authorized ] + to: paid + partially_refund: + from: [ paid, partially_paid, partially_refunded ] + to: partially_refunded + refund: + from: [ paid, partially_paid, partially_refunded ] + to: refunded + callbacks: + after: + sylius_order_paid: + on: [ "pay" ] + do: [ "@sylius.inventory.order_inventory_operator", "sell" ] + args: [ "object" ] + priority: -200 + sylius_pay_suborders: + on: [ "pay" ] + do: [ "@sm.callback.cascade_transition", "apply" ] + args: [ "object.getSecondaryOrders()", "event" ] + priority: -200 + sylius_order_paid_at: + on: [ "pay" ] + do: [ '@bitbag.open_marketplace.component.order.state_machine.order_callbacks', 'setPaidAt' ] + args: [ "object" ] + priority: -200 diff --git a/OpenMarketplace/src/Component/Override/Resources/state_machine/sylius_payment.yaml b/OpenMarketplace/src/Component/Override/Resources/state_machine/sylius_payment.yaml new file mode 100644 index 0000000..ffec4b6 --- /dev/null +++ b/OpenMarketplace/src/Component/Override/Resources/state_machine/sylius_payment.yaml @@ -0,0 +1,54 @@ +winzou_state_machine: + sylius_payment: + class: "%sylius.model.payment.class%" + property_path: state + graph: sylius_payment + state_machine_class: "%sylius.state_machine.class%" + states: + cart: ~ + new: ~ + processing: ~ + authorized: ~ + completed: ~ + failed: ~ + cancelled: ~ + refunded: ~ + transitions: + create: + from: [cart] + to: new + process: + from: [new] + to: processing + authorize: + from: [new, processing] + to: authorized + complete: + from: [new, processing, authorized] + to: completed + fail: + from: [new, processing] + to: failed + cancel: + from: [new, processing, authorized] + to: cancelled + refund: + from: [completed] + to: refunded + callbacks: + after: + sylius_process_order: + on: ["fail", "cancel"] + do: ["@sylius.order_processing.order_payment_processor.after_checkout", "process"] + args: ["object.getOrder()"] + priority: -100 + sylius_resolve_state: + on: ["complete", "process", "refund", "authorize"] + do: ["@sylius.state_resolver.order_payment", "resolve"] + args: ["object.getOrder()"] + priority: -100 + sylius_pay_suborders: + on: ["complete", "process", "refund", "authorize"] + do: [ "@sm.callback.cascade_transition", "apply" ] + args: [ "object.getOrder().getSecondaryPayments()", "event" ] + priority: -200 diff --git a/OpenMarketplace/src/Component/Override/Sylius/Bundle/ApiBundle/ApiPlatform/Bridge/Symfony/Routing/RouteNameResolver.php b/OpenMarketplace/src/Component/Override/Sylius/Bundle/ApiBundle/ApiPlatform/Bridge/Symfony/Routing/RouteNameResolver.php new file mode 100644 index 0000000..aae2485 --- /dev/null +++ b/OpenMarketplace/src/Component/Override/Sylius/Bundle/ApiBundle/ApiPlatform/Bridge/Symfony/Routing/RouteNameResolver.php @@ -0,0 +1,93 @@ +router->getRouteCollection()->all() as $routeName => $route) { + $currentResourceClass = $route->getDefault('_api_resource_class'); + $operation = $route->getDefault(sprintf('_api_%s_operation_name', (string) $operationType)); + $methods = $route->getMethods(); + + if ( + $resourceClass === $currentResourceClass && + null !== $operation && + (empty($methods) || \in_array('GET', $methods, true)) + ) { + if ( + OperationType::SUBRESOURCE === $operationType && + false === $this->isSameSubresource($context, $route->getDefault('_api_subresource_context'))) { + continue; + } + + $matchingRoutes[$routeName] = $route; + } + } + + return $this->returnMatchingRouteName($matchingRoutes, (string) $operationType, $resourceClass); + } + + private function isSameSubresource(array $context, array $currentContext): bool + { + $subresources = array_keys($context['subresource_resources']); + $currentSubresources = []; + + foreach ($currentContext['identifiers'] as [$class]) { + $currentSubresources[] = $class; + } + + return $currentSubresources === $subresources; + } + + private function returnMatchingRouteName( + array $matchingRoutes, + string $operationType, + string $resourceClass, + ): string { + if (1 === count($matchingRoutes)) { + return array_key_first($matchingRoutes); + } + + foreach ($matchingRoutes as $routeName => $route) { + $routePrefix = $this->pathPrefixProvider->getPathPrefix($route->getPath()); + if (null === $routePrefix) { + return $routeName; + } + + $requestPrefix = $this->pathPrefixProvider->getCurrentPrefix(); + if (str_contains((string) $requestPrefix, $routePrefix)) { + return $routeName; + } + } + + throw new InvalidArgumentException( + sprintf('No %s route associated with the type "%s".', $operationType, $resourceClass), + ); + } +} diff --git a/OpenMarketplace/src/Component/Override/Sylius/Bundle/CoreBundle/Doctrine/ORM/Inventory/Operator/OrderInventoryOperator.php b/OpenMarketplace/src/Component/Override/Sylius/Bundle/CoreBundle/Doctrine/ORM/Inventory/Operator/OrderInventoryOperator.php new file mode 100644 index 0000000..754ae3e --- /dev/null +++ b/OpenMarketplace/src/Component/Override/Sylius/Bundle/CoreBundle/Doctrine/ORM/Inventory/Operator/OrderInventoryOperator.php @@ -0,0 +1,57 @@ +decoratedOperator = $decoratedOperator; + } + + public function cancel(BaseOrderInterface $order): void + { + if (!$order instanceof OrderInterface) { + return; + } + if (null !== $order->getPrimaryOrder()) { + $this->decoratedOperator->cancel($order); + } + } + + public function hold(BaseOrderInterface $order): void + { + if (!$order instanceof OrderInterface) { + return; + } + if (null !== $order->getPrimaryOrder()) { + $this->decoratedOperator->hold($order); + } + } + + public function sell(BaseOrderInterface $order): void + { + if (!$order instanceof OrderInterface) { + return; + } + if (null !== $order->getPrimaryOrder()) { + $this->decoratedOperator->sell($order); + } + } +} diff --git a/OpenMarketplace/src/Component/Override/Sylius/Bundle/OrderBundle/NumberAssigner/OrderNumberAssigner.php b/OpenMarketplace/src/Component/Override/Sylius/Bundle/OrderBundle/NumberAssigner/OrderNumberAssigner.php new file mode 100644 index 0000000..ef47a17 --- /dev/null +++ b/OpenMarketplace/src/Component/Override/Sylius/Bundle/OrderBundle/NumberAssigner/OrderNumberAssigner.php @@ -0,0 +1,38 @@ +decoratedOrderNumberAssigner = $decoratedOrderNumberAssigner; + } + + public function assignNumber(OrderInterface $order): void + { + if (null !== $order->getNumber()) { + return; + } + + if ($order->isPrimary()) { + return; + } + + $this->decoratedOrderNumberAssigner->assignNumber($order); + } +} diff --git a/OpenMarketplace/src/Component/Override/Sylius/Bundle/OrderBundle/NumberAssigner/OrderNumberAssignerInterface.php b/OpenMarketplace/src/Component/Override/Sylius/Bundle/OrderBundle/NumberAssigner/OrderNumberAssignerInterface.php new file mode 100644 index 0000000..0edf503 --- /dev/null +++ b/OpenMarketplace/src/Component/Override/Sylius/Bundle/OrderBundle/NumberAssigner/OrderNumberAssignerInterface.php @@ -0,0 +1,21 @@ +getState()) { + return; + } + + if ($order->isEmpty() || !$order->isShippingRequired()) { + $order->removeShipments(); + + return; + } + + $this->addShipmentsPerVendor($order); + + $this->shipmentUnitsRecalculator->recalculateShipmentUnits($order); + } + + private function addShipmentsPerVendor(OrderInterface $order): void + { + $vendors = $order->getVendorsFromOrderItems(); + + foreach ($vendors as $vendor) { + if (true === $order->hasVendorShipment($vendor) || false === $order->hasShippableItemsWithVendor($vendor)) { + continue; + } + + $this->addShipment($order, $vendor); + } + } + + private function addShipment(OrderInterface $order, ?VendorInterface $vendor): void + { + /** @var ShipmentInterface $shipment */ + $shipment = $this + ->shipmentFactory + ->tryCreateNewWithOrderVendorAndDefaultShipment($order, $vendor); + + if (null !== $shipment) { + $order->addShipment($shipment); + } + } +} diff --git a/OpenMarketplace/src/Component/Override/Sylius/Component/Core/OrderProcessing/OrderShipmentProcessorInterface.php b/OpenMarketplace/src/Component/Override/Sylius/Component/Core/OrderProcessing/OrderShipmentProcessorInterface.php new file mode 100644 index 0000000..395bcd3 --- /dev/null +++ b/OpenMarketplace/src/Component/Override/Sylius/Component/Core/OrderProcessing/OrderShipmentProcessorInterface.php @@ -0,0 +1,20 @@ +setProductVariant($productVariant); + $channelPricing->setChannelCode($channelCode); + $channelPricing->setPrice($price); + $channelPricing->setOriginalPrice($originalPrice); + $channelPricing->setMinimumPrice($minimumPrice); + + return $channelPricing; + } + + public function createFromProductListingPrice(ProductVariantInterface $productVariant, ListingPriceInterface $productListingPrice): ChannelPricing + { + $channelPricing = $this->create( + $productVariant, + $productListingPrice->getChannelCode(), + $productListingPrice->getPrice(), + $productListingPrice->getOriginalPrice(), + $productListingPrice->getMinimumPrice(), + ); + + $productVariant->addChannelPricing($channelPricing); + + return $channelPricing; + } +} diff --git a/OpenMarketplace/src/Component/Product/Factory/ChannelPricingFactoryInterface.php b/OpenMarketplace/src/Component/Product/Factory/ChannelPricingFactoryInterface.php new file mode 100644 index 0000000..7c93e3b --- /dev/null +++ b/OpenMarketplace/src/Component/Product/Factory/ChannelPricingFactoryInterface.php @@ -0,0 +1,31 @@ +setTranslatable($draftAttribute->isTranslatable()); + $productAttribute->setStorageType($draftAttribute->getStorageType()); + $productAttribute->setConfiguration($draftAttribute->getConfiguration()); + /** @var VendorInterface $vendor */ + $vendor = $draftAttribute->getVendor(); + $vendorID = $vendor->getId(); + $productAttribute->setCode($draftAttribute->getCode() . '-' . $vendorID); + $productAttribute->setType($draftAttribute->getType()); + $productAttribute->setPosition($draftAttribute->getPosition()); + + return $productAttribute; + } +} diff --git a/OpenMarketplace/src/Component/Product/Factory/ProductAttributeFactoryInterface.php b/OpenMarketplace/src/Component/Product/Factory/ProductAttributeFactoryInterface.php new file mode 100644 index 0000000..38cfeb2 --- /dev/null +++ b/OpenMarketplace/src/Component/Product/Factory/ProductAttributeFactoryInterface.php @@ -0,0 +1,20 @@ +classFQN(); + } + + public function createWithProductAttributeAndValue( + ProductAttributeInterface $productAttribute, + mixed $value + ): ProductAttributeValueInterface { + $productAttributeValue = $this->create(); + $productAttributeValue->setAttribute($productAttribute); + $productAttributeValue->setValue($value); + + return $productAttributeValue; + } +} diff --git a/OpenMarketplace/src/Component/Product/Factory/ProductAttributeValueFactoryInterface.php b/OpenMarketplace/src/Component/Product/Factory/ProductAttributeValueFactoryInterface.php new file mode 100644 index 0000000..cfd1c12 --- /dev/null +++ b/OpenMarketplace/src/Component/Product/Factory/ProductAttributeValueFactoryInterface.php @@ -0,0 +1,25 @@ +setTranslatable($translatable); + $productTranslation->setName($name); + $productTranslation->setDescription($description); + $productTranslation->setSlug($slug); + $productTranslation->setLocale($locale); + $productTranslation->setShortDescription($shortDescription); + $productTranslation->setMetaDescription($metaDescription); + $productTranslation->setMetaKeywords($metaKeywords); + + return $productTranslation; + } + + public function createFromProductListingTranslation(ProductInterface $product, DraftTranslationInterface $translation): ProductTranslation + { + $productTranslation = $this->create( + $product, + $translation->getName(), + $translation->getDescription(), + $translation->getSlug(), + $translation->getLocale(), + $translation->getShortDescription(), + $translation->getMetaDescription(), + $translation->getMetaKeywords() + ); + + $product->addTranslation($productTranslation); + + return $productTranslation; + } +} diff --git a/OpenMarketplace/src/Component/Product/Factory/ProductTranslationFactoryInterface.php b/OpenMarketplace/src/Component/Product/Factory/ProductTranslationFactoryInterface.php new file mode 100644 index 0000000..c719834 --- /dev/null +++ b/OpenMarketplace/src/Component/Product/Factory/ProductTranslationFactoryInterface.php @@ -0,0 +1,38 @@ +setProduct($product); + $productVariant->setCode($product->getCode()); + $productVariant->setEnabled($enabled); + $productVariant->setPosition($position); + $product->addVariant($productVariant); + + return $productVariant; + } +} diff --git a/OpenMarketplace/src/Component/Product/Factory/ProductVariantFactoryInterface.php b/OpenMarketplace/src/Component/Product/Factory/ProductVariantFactoryInterface.php new file mode 100644 index 0000000..a33416c --- /dev/null +++ b/OpenMarketplace/src/Component/Product/Factory/ProductVariantFactoryInterface.php @@ -0,0 +1,26 @@ +setTranslatable($translatable); + $productTranslation->setName($name); + $productTranslation->setLocale($locale); + + return $productTranslation; + } + + public function createFromProductListingTranslation( + ProductVariantInterface $productVariant, + DraftTranslationInterface $translation + ): ProductVariantTranslation { + $productTranslation = $this->create( + $productVariant, + $translation->getName(), + $translation->getLocale(), + ); + + $productVariant->addTranslation($productTranslation); + + return $productTranslation; + } +} diff --git a/OpenMarketplace/src/Component/Product/Factory/ProductVariantTranslationFactoryInterface.php b/OpenMarketplace/src/Component/Product/Factory/ProductVariantTranslationFactoryInterface.php new file mode 100644 index 0000000..a30cbdc --- /dev/null +++ b/OpenMarketplace/src/Component/Product/Factory/ProductVariantTranslationFactoryInterface.php @@ -0,0 +1,30 @@ +deleted; + } + + public function setDeleted(bool $deleted): void + { + $this->deleted = $deleted; + } + + public function resetImages(): void + { + $this->images = new ArrayCollection(); + } + + public function hasVendor(): bool + { + return isset($this->vendor); + } + + public function getVendor(): ?VendorInterface + { + return $this->vendor; + } + + public function setVendor(?VendorInterface $vendor): void + { + $this->vendor = $vendor; + } + + public function setAttributesFrom(DraftInterface $draft): void + { + $this->attributes = $draft->getAttributes(); + } + + public function setChannels(Collection $channels): void + { + $this->channels = $channels; + } +} diff --git a/OpenMarketplace/src/Component/Product/Repository/ProductRepository.php b/OpenMarketplace/src/Component/Product/Repository/ProductRepository.php new file mode 100644 index 0000000..9e98b47 --- /dev/null +++ b/OpenMarketplace/src/Component/Product/Repository/ProductRepository.php @@ -0,0 +1,50 @@ +_em->persist($product); + $this->_em->flush(); + } + + public function createVendorShopListQueryBuilder( + VendorInterface $vendor, + ChannelInterface $channel, + TaxonInterface $taxon, + string $locale, + array $sorting = [], + bool $includeAllDescendants = false + ): QueryBuilder { + $qb = $this->createShopListQueryBuilder( + $channel, + $taxon, + $locale, + $sorting, + $includeAllDescendants, + ); + + return $qb + ->andWhere('o.vendor = :vendor') + ->setParameter('vendor', $vendor) + ; + } +} diff --git a/OpenMarketplace/src/Component/Product/Repository/ProductRepositoryInterface.php b/OpenMarketplace/src/Component/Product/Repository/ProductRepositoryInterface.php new file mode 100644 index 0000000..a583a4a --- /dev/null +++ b/OpenMarketplace/src/Component/Product/Repository/ProductRepositoryInterface.php @@ -0,0 +1,33 @@ +createQueryBuilder('pr'); + + return $qb->innerJoin('pr.reviewSubject', 'rs') + ->andWhere($qb->expr()->eq('rs.vendor', ':vendorId')) + ->setParameter('vendorId', $vendor->getId(), Types::BIGINT) + ; + } +} diff --git a/OpenMarketplace/src/Component/Product/Repository/ProductReviewRepositoryInterface.php b/OpenMarketplace/src/Component/Product/Repository/ProductReviewRepositoryInterface.php new file mode 100644 index 0000000..8b976cc --- /dev/null +++ b/OpenMarketplace/src/Component/Product/Repository/ProductReviewRepositoryInterface.php @@ -0,0 +1,14 @@ +getId(); + + return $this->createQueryBuilder('v') + ->innerJoin('v.product', 'p') + ->andWhere('p.vendor = :vendor') + ->setParameter('vendor', $vendorId) + ; + } +} diff --git a/OpenMarketplace/src/Component/Product/Resources/doctrine/Product.orm.xml b/OpenMarketplace/src/Component/Product/Resources/doctrine/Product.orm.xml new file mode 100644 index 0000000..7ff3f81 --- /dev/null +++ b/OpenMarketplace/src/Component/Product/Resources/doctrine/Product.orm.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Product/Resources/services.xml b/OpenMarketplace/src/Component/Product/Resources/services.xml new file mode 100644 index 0000000..ba5212c --- /dev/null +++ b/OpenMarketplace/src/Component/Product/Resources/services.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Product/Resources/services/factories.xml b/OpenMarketplace/src/Component/Product/Resources/services/factories.xml new file mode 100644 index 0000000..00d83f8 --- /dev/null +++ b/OpenMarketplace/src/Component/Product/Resources/services/factories.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %sylius.model.product_attribute_value.class% + + + + diff --git a/OpenMarketplace/src/Component/Product/Resources/services/repositories.xml b/OpenMarketplace/src/Component/Product/Resources/services/repositories.xml new file mode 100644 index 0000000..d71d420 --- /dev/null +++ b/OpenMarketplace/src/Component/Product/Resources/services/repositories.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/DraftConverter.php b/OpenMarketplace/src/Component/ProductListing/DraftConverter.php new file mode 100644 index 0000000..a8f6a8f --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftConverter.php @@ -0,0 +1,58 @@ +getProductListing(); + if (!$productListing->getProduct()) { + $product = $this->simpleProductFactory->create($productDraft); + $this->imagesOperator->copyFilesToProduct($productDraft, $product); + $this->taxonsOperator->copyTaxonsToProduct($productDraft, $product); + $this->attributesOperator->convert($productDraft, $product); + $productListing->accept(); + + return $product; + } + + /** @var BitBagProductInterface $product */ + $product = $this->productFromDraftUpdater->update($productDraft); + + $this->imagesOperator->removeOldFiles($product); + $this->imagesOperator->copyFilesToProduct($productDraft, $product); + $this->taxonsOperator->updateTaxonsInProduct($productDraft, $product); + $this->attributesOperator->convert($productDraft, $product); + $productListing->accept(); + + return $product; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftConverter/Cloner/AttributeTranslationCloner.php b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Cloner/AttributeTranslationCloner.php new file mode 100644 index 0000000..d849ed3 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Cloner/AttributeTranslationCloner.php @@ -0,0 +1,39 @@ +getTranslations(); + /** @var DraftAttributeTranslationInterface $translation */ + foreach ($translations as $translation) { + $newTranslation = $this->attributeTranslationFactory->create(); + $newTranslation->setLocale($translation->getLocale()); + $newTranslation->setName($translation->getName()); + $newTranslation->setTranslatable($draftAttribute->getProductAttribute()); + $this->entityManager->persist($newTranslation); + } + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftConverter/Cloner/AttributeTranslationClonerInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Cloner/AttributeTranslationClonerInterface.php new file mode 100644 index 0000000..029ca33 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Cloner/AttributeTranslationClonerInterface.php @@ -0,0 +1,19 @@ +getAttributes(); + foreach ($attributeValues as $draftAttributeValue) { + /** @var DraftAttributeInterface $draftAttribute */ + $draftAttribute = $draftAttributeValue->getAttribute(); + $productAttribute = $draftAttribute->getProductAttribute(); + $newProductAttributeValue = $this->attributeValueFactory->create(); + $newProductAttributeValue->setSubject($product); + $newProductAttributeValue->setAttribute($productAttribute); + $newProductAttributeValue->setLocaleCode($draftAttributeValue->getLocaleCode()); + $newProductAttributeValue->setValue($draftAttributeValue->getValue()); + $this->entityManager->persist($newProductAttributeValue); + } + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftConverter/Cloner/AttributeValueClonerInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Cloner/AttributeValueClonerInterface.php new file mode 100644 index 0000000..2d4199c --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Cloner/AttributeValueClonerInterface.php @@ -0,0 +1,20 @@ + $productDraftAttributeValues + * + * @return array + */ + public function extract(Collection $productDraftAttributeValues): array + { + $attributes = []; + foreach ($productDraftAttributeValues as $attributeValue) { + $attribute = $attributeValue->getAttribute(); + if (!in_array($attribute, $attributes)) { + $attributes[] = $attribute; + } + } + + return $attributes; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftConverter/Extractor/DraftAttributesExtractorInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Extractor/DraftAttributesExtractorInterface.php new file mode 100644 index 0000000..e7b8788 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Extractor/DraftAttributesExtractorInterface.php @@ -0,0 +1,26 @@ + $productDraftAttributeValues + * + * @return array + */ + public function extract(Collection $productDraftAttributeValues): array; +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftConverter/Operator/AttributesOperator.php b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Operator/AttributesOperator.php new file mode 100644 index 0000000..88b65a3 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Operator/AttributesOperator.php @@ -0,0 +1,59 @@ +getAttributes(); + $attributes = $this->attributesExtractor->extract($attributeValues); + + $oldProductAttributeValues = $product->getAttributes(); + + foreach ($oldProductAttributeValues as $oldProductAttributeValue) { + $this->entityManager->remove($oldProductAttributeValue); + } + + $this->entityManager->flush(); + + /** @var DraftAttributeInterface $draftAttribute */ + foreach ($attributes as $draftAttribute) { + if (!$draftAttribute->getProductAttribute()) { + $newProductAttribute = $this->productAttributeFactory->createClone($draftAttribute); + $draftAttribute->setProductAttribute($newProductAttribute); + $this->entityManager->persist($newProductAttribute); + $this->attributeTranslationCloner->clone($draftAttribute); + } + } + + $this->attributeValueCloner->clone($productDraft, $product); + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftConverter/Operator/AttributesOperatorInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Operator/AttributesOperatorInterface.php new file mode 100644 index 0000000..e059c1e --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Operator/AttributesOperatorInterface.php @@ -0,0 +1,20 @@ +getImages() as $image) { + $newImage = $this->productImageFactory->createNew(); + + $newImage->setType($image->getType()); + $newImage->setOwner($cratedProduct); + + /** @var string $key */ + $key = $image->getPath(); + $nameSuffix = '-new.'; + + /** @var string $file */ + $file = $this->filesystem->read($key); + + $path = explode('.', $key)[0]; + $fileType = explode('.', $key)[1]; + + $newKey = $path . $nameSuffix . $fileType; + + $this->filesystem->write($newKey, $file, true); + + $newImage->setPath($newKey); + + $cratedProduct->addImage($newImage); + } + } + + public function removeOldFiles(ProductInterface $product): void + { + foreach ($product->getImages() as $image) { + /** @var string $key */ + $key = $image->getPath(); + if ($this->filesystem->has($key)) { + $this->filesystem->delete($key); + } + } + $product->resetImages(); + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftConverter/Operator/ImagesOperatorInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Operator/ImagesOperatorInterface.php new file mode 100644 index 0000000..f929682 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Operator/ImagesOperatorInterface.php @@ -0,0 +1,22 @@ +getMainTaxon(); + $product->setMainTaxon($productDraftMainTaxon); + + $taxonIdsFromProduct = $this->getTaxonIdsForProduct($product); + + $taxonIdsFromProductDraft = $this->getTaxonIdsForProductDraft($productDraft); + + $sharedTaxonIds = array_intersect($taxonIdsFromProduct, $taxonIdsFromProductDraft); + + /** @var DraftTaxonInterface $productDraftTaxon */ + foreach ($productDraft->getProductDraftTaxons() as $productDraftTaxon) { + /** @var TaxonInterface $taxon */ + $taxon = $productDraftTaxon->getTaxon(); + if (!in_array($taxon->getId(), $sharedTaxonIds)) { + /** @var ProductTaxonInterface $productTaxon */ + $productTaxon = $this->productTaxonFactory->createNew(); + $productTaxon->setProduct($product); + $productTaxon->setTaxon($productDraftTaxon->getTaxon()); + $product->addProductTaxon($productTaxon); + } + } + + return $product; + } + + public function updateTaxonsInProduct(DraftInterface $productDraft, ProductInterface $product): void + { + if (null != $product->getMainTaxon()) { + $product->setMainTaxon(null); + } + + $taxonIdsFromProduct = $this->getTaxonIdsForProduct($product); + + $taxonIdsFromProductDraft = $this->getTaxonIdsForProductDraft($productDraft); + + $sharedTaxonIds = array_intersect($taxonIdsFromProduct, $taxonIdsFromProductDraft); + + /** @var ProductTaxon $productTaxon */ + foreach ($product->getProductTaxons() as $productTaxon) { + /** @var TaxonInterface $taxon */ + $taxon = $productTaxon->getTaxon(); + if (!in_array($taxon->getId(), $sharedTaxonIds)) { + $product->removeProductTaxon($productTaxon); + $this->entityManager->remove($productTaxon); + } + } + + $this->copyTaxonsToProduct($productDraft, $product); + } + + private function getTaxonIdsForProduct(ProductInterface $product): array + { + $taxonIds = []; + foreach ($product->getProductTaxons() as $productTaxon) { + /** @var TaxonInterface $taxon */ + $taxon = $productTaxon->getTaxon(); + $taxonIds[] = $taxon->getId(); + } + + return $taxonIds; + } + + private function getTaxonIdsForProductDraft(DraftInterface $productDraft): array + { + $taxonIds = []; + foreach ($productDraft->getProductDraftTaxons() as $productDraftTaxon) { + /** @var TaxonInterface $taxon */ + $taxon = $productDraftTaxon->getTaxon(); + $taxonIds[] = $taxon->getId(); + } + + return $taxonIds; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftConverter/Operator/TaxonsOperatorInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Operator/TaxonsOperatorInterface.php new file mode 100644 index 0000000..a698b47 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Operator/TaxonsOperatorInterface.php @@ -0,0 +1,22 @@ +productFactory->createNew(); + $product = $this->setSimpleProductProperties($product, $productDraft); + + $productDraft->getProductListing()->setProduct($product); + + return $product; + } + + private function setSimpleProductProperties(ProductInterface $product, DraftInterface $productDraft): ProductInterface + { + $now = new \DateTime(); + + $vendor = $productDraft->getProductListing()->getVendor(); + $vendorID = $vendor->getId(); + $product->setCode($productDraft->getCode() . '-' . $vendorID); + $product->setEnabled(true); + $product->setUpdatedAt($now); + $product->setCreatedAt($now); + $product->setVendor($productDraft->getProductListing()->getVendor()); + $product->setChannels($productDraft->getChannels()); + + /** @var DraftTranslationInterface $translation */ + foreach ($productDraft->getTranslations() as $translation) { + $this->productTranslationFactory->createFromProductListingTranslation($product, $translation); + } + + $productVariant = $this->productVariantFactory->createNewForProduct($product, true, 0); + $productVariant->setShippingRequired($productDraft->isShippingRequired()); + $productVariant->setShippingCategory($productDraft->getShippingCategory()); + $productVariant->setTaxCategory($productDraft->getTaxCategory()); + + /** @var DraftTranslationInterface $translation */ + foreach ($productDraft->getTranslations() as $translation) { + $this->productVariantTranslationFactory->createFromProductListingTranslation($productVariant, $translation); + } + + $channelPricingCodes = []; + /** @var ListingPriceInterface $productListingPrice */ + foreach ($productDraft->getProductListingPrices() as $productListingPrice) { + if (!in_array($productListingPrice->getChannelCode(), $channelPricingCodes)) { + $channelPricingCodes[] = $productListingPrice->getChannelCode(); + } + + $this->channelPricingFactory->createFromProductListingPrice($productVariant, $productListingPrice); + } + + return $product; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftConverter/SimpleProductFactoryInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftConverter/SimpleProductFactoryInterface.php new file mode 100644 index 0000000..182d2f4 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftConverter/SimpleProductFactoryInterface.php @@ -0,0 +1,20 @@ +getProductListing()->getProduct(); + + if (!$product) { + throw new ProductNotFoundException('Product not found.'); + } + + return $this->updateProduct($product, $productDraft); + } + + private function updateProduct(ProductInterface $product, DraftInterface $productDraft): ProductInterface + { + $product->setUpdatedAt(new \DateTime()); + $product->setChannels($productDraft->getChannels()); + + $productTranslations = $this->productTranslationRepository->findBy(['translatable' => $product]); + $mappedProductTranslations = []; + + /** @var BaseProductTranslationInterface $productTranslation */ + foreach ($productTranslations as $productTranslation) { + $mappedProductTranslations[$productTranslation->getLocale()] = $productTranslation; + } + + /** @var DraftTranslationInterface $translation */ + foreach ($productDraft->getTranslations() as $translation) { + $productTranslation = null; + $translationLocale = $translation->getLocale(); + if (null === $translationLocale) { + throw new LocaleNotFoundException('Locale not found.'); + } + if (array_key_exists($translationLocale, $mappedProductTranslations)) { + $productTranslation = $mappedProductTranslations[$translation->getLocale()]; + unset($mappedProductTranslations[$translation->getLocale()]); + } + + if (null !== $productTranslation) { + $productTranslation->setName($translation->getName()); + $productTranslation->setDescription($translation->getDescription()); + $productTranslation->setSlug($translation->getSlug()); + $productTranslation->setShortDescription($translation->getShortDescription()); + $productTranslation->setMetaDescription($translation->getMetaDescription()); + $productTranslation->setMetaKeywords($translation->getMetaKeywords()); + } else { + $this->productTranslationFactory->createFromProductListingTranslation($product, $translation); + } + } + + foreach ($mappedProductTranslations as $deletedProductTranslation) { + $product->removeTranslation($deletedProductTranslation); + } + + /** @var ProductVariant $productVariant */ + $productVariant = $this->productVariantRepository->findOneBy(['product' => $product]); + $productVariant->setShippingRequired($productDraft->isShippingRequired()); + $productVariant->setShippingCategory($productDraft->getShippingCategory()); + $productVariant->setTaxCategory($productDraft->getTaxCategory()); + + /** @var ListingPriceInterface $productListingPrice */ + foreach ($productDraft->getProductListingPrices() as $productListingPrice) { + /** @var ChannelPricing $channelPricing */ + $channelPricing = $this->channelPricingRepository->findOneBy(['productVariant' => $productVariant, 'channelCode' => $productListingPrice->getChannelCode()]); + + if (null !== $channelPricing) { + $channelPricing->setPrice($productListingPrice->getPrice()); + $channelPricing->setOriginalPrice($productListingPrice->getOriginalPrice()); + $channelPricing->setMinimumPrice($productListingPrice->getMinimumPrice()); + } + } + + return $product; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftConverter/SimpleProductUpdaterInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftConverter/SimpleProductUpdaterInterface.php new file mode 100644 index 0000000..46d7a0d --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftConverter/SimpleProductUpdaterInterface.php @@ -0,0 +1,20 @@ +setPosition($productAttribute->getPosition()); + + $productAttributeTranslations = $productAttribute->getTranslations(); + foreach ($productAttributeTranslations as $translation) { + $this->entityManager->remove($translation); + } + $this->attributeTranslationCloner->clone($draftAttribute); + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftConverter/Updater/ProductAttributeUpdaterInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Updater/ProductAttributeUpdaterInterface.php new file mode 100644 index 0000000..05cf7d9 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftConverter/Updater/ProductAttributeUpdaterInterface.php @@ -0,0 +1,20 @@ +getAttributes() as $baseAttribute) { + $attribute = $baseAttribute->getAttribute(); + Assert::isInstanceOf($attribute, DraftAttributeInterface::class); + + $attributeValue = $this->draftAttributeValueFactory->createForAttribute($attribute, $to); + $attributeValue->setValue($baseAttribute->getValue()); + $to->addAttribute($attributeValue); + + $this->entityManager->persist($attributeValue); + } + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftAttributesClonerInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftAttributesClonerInterface.php new file mode 100644 index 0000000..39d3cb3 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftAttributesClonerInterface.php @@ -0,0 +1,22 @@ +setProductListing($base->getProductListing()); + $destination->setCode($base->getCode()); + $destination->setShippingRequired($base->isShippingRequired()); + $destination->setShippingCategory($base->getShippingCategory()); + $destination->setChannels($base->getChannels()); + $destination->setMainTaxon($base->getMainTaxon()); + $destination->setTaxCategory($base->getTaxCategory()); + + $destination->clearProductDraftTaxons(); + $this->draftTaxonCloner->clone($base, $destination); + + $destination->clearAttributes(); + $this->draftAttributesCloner->clone($base, $destination); + + $destination->clearImages(); + $this->draftImagesCloner->clone($base, $destination); + + $this->draftTranslationCloner->clone($base, $destination); + $this->draftPricingCloner->clone($base, $destination); + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftClonerInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftClonerInterface.php new file mode 100644 index 0000000..305653b --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftClonerInterface.php @@ -0,0 +1,22 @@ +getImages(); + + /** @var DraftImageInterface $baseImage */ + foreach ($baseImages as $baseImage) { + $newImage = $this->draftImageFactory->createForDraft($to); + $newImage->setType($baseImage->getType()); + $newImage->setFile($baseImage->getFile()); + + $baseImagePath = sprintf('%s/%s', $this->imageUploadPath, $baseImage->getPath()); + $newUploadedImage = new UploadedFile($baseImagePath, basename($baseImagePath)); + $newImage->setFile($newUploadedImage); + $newImage->setPath($baseImage->getPath()); + + $to->addImage($newImage); + } + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftImagesClonerInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftImagesClonerInterface.php new file mode 100644 index 0000000..37aaff1 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftImagesClonerInterface.php @@ -0,0 +1,22 @@ +getProductListingPrices() as $price) { + /** @var ListingPriceInterface $newPrice */ + $newPrice = $this->priceFactory->createForChannelCode( + $price->getChannelCode(), + $price->getProductDraft() + ); + + $newPrice->setPrice($price->getPrice()); + $newPrice->setMinimumPrice($price->getMinimumPrice()); + $newPrice->setOriginalPrice($price->getOriginalPrice()); + $to->addProductListingPriceWithKey($newPrice, $newPrice->getChannelCode()); + } + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftPricingClonerInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftPricingClonerInterface.php new file mode 100644 index 0000000..10caa10 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftPricingClonerInterface.php @@ -0,0 +1,19 @@ +getProductDraftTaxons() as $baseDraftTaxon) { + $taxon = $baseDraftTaxon->getTaxon(); + Assert::isInstanceOf($taxon, TaxonInterface::class); + + $draftTaxon = $this->draftTaxonFactory->createForTaxon( + $taxon, + $to + ); + $draftTaxon->setPosition($baseDraftTaxon->getPosition()); + $to->addProductDraftTaxon($draftTaxon); + + $this->entityManager->persist($draftTaxon); + } + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftTaxonClonerInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftTaxonClonerInterface.php new file mode 100644 index 0000000..6e9ab51 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftTaxonClonerInterface.php @@ -0,0 +1,22 @@ +getTranslations() as $translation) { + $locale = $translation->getLocale(); + if (null === $locale) { + throw new LocaleNotFoundException('Locale not found.'); + } + + /** @var DraftTranslationInterface $newTranslation */ + $newTranslation = $this->translationFactory->createNew(); + $newTranslation->setName($translation->getName()); + $newTranslation->setProductDraft($to); + $newTranslation->setDescription($translation->getDescription()); + $newTranslation->setLocale($locale); + $newTranslation->setMetaDescription($translation->getMetaDescription()); + $newTranslation->setMetaKeywords($translation->getMetaKeywords()); + $newTranslation->setSlug($translation->getSlug()); + $newTranslation->setShortDescription($translation->getShortDescription()); + $to->addTranslationWithKey($newTranslation, $locale); + } + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftTranslationClonerInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftTranslationClonerInterface.php new file mode 100644 index 0000000..e0a6f32 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Cloner/DraftTranslationClonerInterface.php @@ -0,0 +1,19 @@ +getLatestDraft(); + Assert::isInstanceOf($latestDraft, DraftInterface::class); + + if ($listing->needsNewDraft()) { + $newProductDraft = $this->createNextDraft($latestDraft); + $listing->insertDraft($newProductDraft); + + // Important. The flush here prevents to re-upload trashy images on every render the listing edit form + $this->entityManager->flush(); + } + + $currentLatestDraft = $listing->getLatestDraft(); + Assert::isInstanceOf($currentLatestDraft, DraftInterface::class); + + return $currentLatestDraft; + } + + private function createNextDraft(DraftInterface $base): DraftInterface + { + $destination = $this->draftFactory->createNew(); + $destination->markAsCreated(); + + $this->draftCloner->clone($base, $destination); + + $destination->setVersionNumber($base->getVersionNumber()); + $destination->incrementVersion(); + + return $destination; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftGenerator/DraftGeneratorInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/DraftGeneratorInterface.php new file mode 100644 index 0000000..d2f3d38 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/DraftGeneratorInterface.php @@ -0,0 +1,20 @@ +attributeTypesRegistry->get($type); + /** @var DraftAttributeInterface $attribute */ + $attribute = $this->resourceFactory->createNew(); + $attribute->setType($type); + $attribute->setStorageType($attributeType->getStorageType()); + $attribute->setVendor($vendor); + + return $attribute; + } + + public function createNew(): object + { + return $this->resourceFactory->createNew(); + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Factory/DraftAttributeFactoryInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Factory/DraftAttributeFactoryInterface.php new file mode 100644 index 0000000..e81f681 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Factory/DraftAttributeFactoryInterface.php @@ -0,0 +1,24 @@ +setAttribute($draftAttribute); + $attributeValue->setSubject($draft); + + return $attributeValue; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Factory/DraftAttributeValueFactoryInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Factory/DraftAttributeValueFactoryInterface.php new file mode 100644 index 0000000..69b4ee2 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Factory/DraftAttributeValueFactoryInterface.php @@ -0,0 +1,17 @@ +createNew(); + $image->setOwner($productDraft); + + return $image; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Factory/DraftImageFactoryInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Factory/DraftImageFactoryInterface.php new file mode 100644 index 0000000..a0ce8e3 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Factory/DraftImageFactoryInterface.php @@ -0,0 +1,22 @@ +resourceFactory->createNew(); + $price->setChannelCode($channelCode); + $price->setProductDraft($draft); + + return $price; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Factory/DraftPricingFactoryInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Factory/DraftPricingFactoryInterface.php new file mode 100644 index 0000000..01759c7 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Factory/DraftPricingFactoryInterface.php @@ -0,0 +1,23 @@ +setTaxon($taxon); + $draftTaxon->setProductDraft($draft); + + return $draftTaxon; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Factory/DraftTaxonFactoryInterface.php b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Factory/DraftTaxonFactoryInterface.php new file mode 100644 index 0000000..f31a4c9 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/DraftGenerator/Factory/DraftTaxonFactoryInterface.php @@ -0,0 +1,17 @@ + */ + protected Collection $images; + + /** @var Collection */ + protected Collection $translations; + + /** @var Collection */ + protected Collection $productListingPrices; + + protected ?ListingInterface $productListing = null; + + /** @var Collection */ + protected Collection $attributes; + + protected TaxonInterface|null $mainTaxon; + + /** @var Collection */ + protected Collection $productDraftTaxons; + + /** @var Collection */ + protected Collection $channels; + + protected ?TaxCategoryInterface $taxCategory = null; + + public function __construct() + { + $this->images = new ArrayCollection(); + $this->code = ''; + $this->status = DraftInterface::STATUS_CREATED; + $this->productListingPrices = new ArrayCollection(); + $this->translations = new ArrayCollection(); + $this->isVerified = false; + $this->createdAt = new \DateTime(); + $this->versionNumber = 1; + $this->attributes = new ArrayCollection(); + $this->mainTaxon = null; + $this->productDraftTaxons = new ArrayCollection(); + $this->channels = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function getUuid(): ?UuidInterface + { + return $this->uuid; + } + + public function setUuid(?UuidInterface $uuid): void + { + $this->uuid = $uuid; + } + + public function setId(?int $id): void + { + $this->id = $id; + } + + public function getCode(): string + { + return $this->code; + } + + public function setCode(string $code): void + { + $this->code = $code; + } + + public function isShippingRequired(): bool + { + return $this->shippingRequired; + } + + public function setShippingRequired(bool $shippingRequired): void + { + $this->shippingRequired = $shippingRequired; + } + + public function getShippingCategory(): ?ShippingCategoryInterface + { + return $this->shippingCategory; + } + + public function setShippingCategory(?ShippingCategoryInterface $shippingCategory): void + { + $this->shippingCategory = $shippingCategory; + } + + public function isVerified(): bool + { + return $this->isVerified; + } + + public function setIsVerified(bool $isVerified): void + { + $this->isVerified = $isVerified; + } + + public function getVerifiedAt(): ?\DateTimeInterface + { + return $this->verifiedAt; + } + + public function setVerifiedAt(?\DateTimeInterface $verifiedAt): void + { + $this->verifiedAt = $verifiedAt; + } + + public function getPublishedAt(): ?\DateTimeInterface + { + return $this->publishedAt; + } + + public function setPublishedAt(?\DateTimeInterface $publishedAt): void + { + $this->publishedAt = $publishedAt; + } + + public function getCreatedAt(): \DateTimeInterface + { + return $this->createdAt; + } + + public function setCreatedAt(\DateTimeInterface $createdAt): void + { + $this->createdAt = $createdAt; + } + + public function getVersionNumber(): int + { + return $this->versionNumber; + } + + public function setVersionNumber(int $versionNumber): void + { + $this->versionNumber = $versionNumber; + } + + /** @return Collection */ + public function getTranslations(): Collection + { + return $this->translations; + } + + /** @param Collection $translations */ + public function setTranslations(Collection $translations): void + { + $this->translations = $translations; + } + + public function addTranslation(DraftTranslationInterface $translation): void + { + $this->translations->add($translation); + } + + public function removeTranslation(DraftTranslationInterface $translation): void + { + $this->translations->removeElement($translation); + } + + public function getProductListingPrices(): Collection + { + return $this->productListingPrices; + } + + public function addProductListingPrice(ListingPriceInterface $productListingPrice): void + { + $productListingPrice->setProductDraft($this); + $this->productListingPrices->add($productListingPrice); + } + + public function removeProductListingPrice(ListingPriceInterface $productListingPrice): void + { + $this->productListingPrices->removeElement($productListingPrice); + } + + public function getVendor(): VendorInterface + { + return $this->getProductListing()->getVendor(); + } + + public function getProductListing(): ListingInterface + { + Assert::isInstanceOf($this->productListing, ListingInterface::class); + + return $this->productListing; + } + + public function setProductListing(ListingInterface $productListing): void + { + $this->productListing = $productListing; + } + + public function getStatus(): string + { + return $this->status; + } + + public function setStatus(string $status): void + { + $this->status = $status; + } + + public function incrementVersion(): void + { + ++$this->versionNumber; + } + + public function addTranslationWithKey(DraftTranslationInterface $translation, string $key): void + { + $this->translations->set($key, $translation); + } + + public function addProductListingPriceWithKey(ListingPriceInterface $productListingPrice, string $key): void + { + $this->productListingPrices->set($key, $productListingPrice); + } + + public function accept(): void + { + $this->setStatus(DraftInterface::STATUS_VERIFIED); + $this->setVerifiedAt((new \DateTime())); + $this->setIsVerified(true); + } + + public function reject(): void + { + $this->setStatus(DraftInterface::STATUS_REJECTED); + $this->setVerifiedAt((new \DateTime())); + } + + public function sendToVerification(): void + { + $this->setStatus(DraftInterface::STATUS_UNDER_VERIFICATION); + $this->setPublishedAt((new \DateTime())); + } + + public function getImages(): Collection + { + return $this->images; + } + + public function setImages(Collection $images): void + { + $this->images = $images; + } + + public function addImage(ImageInterface $image): void + { + $this->images->add($image); + } + + public function removeImage(ImageInterface $image): void + { + $this->images->removeElement($image); + } + + public function clearImages(): void + { + $this->images->clear(); + } + + public function getAttributes(): Collection + { + return $this->attributes; + } + + public function getAttributesByLocale( + string $localeCode, + string $fallbackLocaleCode, + ?string $baseLocaleCode = null + ): Collection { + if (null === $baseLocaleCode || $baseLocaleCode === $fallbackLocaleCode) { + $baseLocaleCode = $fallbackLocaleCode; + $fallbackLocaleCode = null; + } + + $attributes = $this->attributes->filter( + function (AttributeValueInterface $attribute) use ($baseLocaleCode) { + return $attribute->getLocaleCode() === $baseLocaleCode || null === $attribute->getLocaleCode(); + } + ); + + $attributesWithFallback = []; + + /** @var DraftAttributeValueInterface $attribute */ + foreach ($attributes as $attribute) { + $attributesWithFallback[] = $this->getAttributeInDifferentLocale($attribute, $localeCode, $fallbackLocaleCode); + } + + /** @var Collection $collection */ + $collection = new ArrayCollection($attributesWithFallback); + + return $collection; + } + + public function addAttribute(AttributeValueInterface $attribute): void + { + if ($this->hasAttribute($attribute)) { + return; + } + + if ($attribute instanceof DraftAttributeValueInterface) { + $attribute->setDraft($this); + $this->attributes->add($attribute); + } + } + + /** @param DraftAttributeValueInterface $attribute */ + public function removeAttribute(AttributeValueInterface $attribute): void + { + if (!$this->hasAttribute($attribute)) { + return; + } + + $this->attributes->removeElement($attribute); + $attribute->setDraft(null); + } + + public function clearAttributes(): void + { + $this->attributes->clear(); + } + + public function hasAttribute(AttributeValueInterface $attribute): bool + { + return $this->attributes->contains($attribute); + } + + public function hasAttributeByCodeAndLocale(string $attributeCode, ?string $localeCode = null): bool + { + foreach ($this->attributes as $attribute) { + if (null === $attribute->getAttribute()) { + continue; + } + $actualAttributeCode = $attribute->getAttribute()->getCode(); + $actualLocaleCode = $attribute->getLocaleCode(); + if ($actualAttributeCode === $attributeCode + && ($actualLocaleCode === $localeCode || null === $attribute->getLocaleCode())) { + return true; + } + } + + return false; + } + + public function getAttributeByCodeAndLocale(string $attributeCode, ?string $localeCode = null): ?AttributeValueInterface + { + foreach ($this->attributes as $attribute) { + if (null === $attribute->getAttribute()) { + continue; + } + $actualAttributeCode = $attribute->getAttribute()->getCode(); + $actualLocaleCode = $attribute->getLocaleCode(); + if ($actualAttributeCode === $attributeCode && + ($actualLocaleCode === $localeCode || null === $actualLocaleCode)) { + return $attribute; + } + } + + return null; + } + + protected function getAttributeInDifferentLocale( + DraftAttributeValueInterface $attributeValue, + string $localeCode, + ?string $fallbackLocaleCode = null + ): ?AttributeValueInterface { + $attributeCode = $attributeValue->getCode(); + + if (null === $attributeCode) { + return null; + } + if (!$this->hasNotEmptyAttributeByCodeAndLocale($attributeCode, $localeCode)) { + return $attributeValue; + } + + if ( + null !== $fallbackLocaleCode && + $this->hasNotEmptyAttributeByCodeAndLocale($attributeCode, $fallbackLocaleCode) + ) { + return $this->getAttributeByCodeAndLocale($attributeCode, $fallbackLocaleCode); + } + + /** @var AttributeValueInterface $attribute */ + $attribute = $this->getAttributeByCodeAndLocale($attributeCode, $localeCode); + + return $attribute; + } + + protected function hasNotEmptyAttributeByCodeAndLocale(string $attributeCode, string $localeCode): bool + { + $attributeValue = $this->getAttributeByCodeAndLocale($attributeCode, $localeCode); + if (null === $attributeValue) { + return false; + } + + $value = $attributeValue->getValue(); + if ('' === $value || null === $value || [] === $value) { + return false; + } + + return true; + } + + protected function createTranslation(): DraftTranslationInterface + { + return new DraftTranslation(); + } + + /** @return Collection */ + public function getProductDraftTaxons(): Collection + { + return $this->productDraftTaxons; + } + + public function addProductDraftTaxon(DraftTaxonInterface $productDraftTaxons): void + { + if (!$this->hasProductDraftTaxon($productDraftTaxons)) { + $this->productDraftTaxons->add($productDraftTaxons); + $productDraftTaxons->setProductDraft($this); + } + } + + public function removeProductDraftTaxon(DraftTaxonInterface $productDraftTaxons): void + { + if ($this->hasProductDraftTaxon($productDraftTaxons)) { + $this->productDraftTaxons->removeElement($productDraftTaxons); + } + } + + public function clearProductDraftTaxons(): void + { + $this->productDraftTaxons->clear(); + } + + public function hasProductDraftTaxon(DraftTaxonInterface $productDraftTaxons): bool + { + return $this->productDraftTaxons->contains($productDraftTaxons); + } + + /** @return Collection */ + public function getTaxons(): Collection + { + return $this->productDraftTaxons->map(function (DraftTaxonInterface $productDraftTaxons): ?TaxonInterface { + return $productDraftTaxons->getTaxon(); + }); + } + + public function hasTaxon(TaxonInterface $taxon): bool + { + return $this->getTaxons()->contains($taxon); + } + + public function getMainTaxon(): TaxonInterface|null + { + return $this->mainTaxon; + } + + public function setMainTaxon(?TaxonInterface $mainTaxon): void + { + $this->mainTaxon = $mainTaxon; + } + + public function getTranslationByLocale(string $locale): ?DraftTranslationInterface + { + foreach ($this->getTranslations() as $translation) { + if ($translation->getLocale() == $locale) { + return $translation; + } + } + + return null; + } + + public function getName(string $locale): ?string + { + $translation = $this->getTranslationByLocale($locale); + + return $translation?->getName(); + } + + public function getSlug(string $locale): ?string + { + $translation = $this->getTranslationByLocale($locale); + + return $translation?->getSlug(); + } + + public function getAnyTranslationName(): ?string + { + foreach ($this->translations as $translation) { + if (null !== $translation->getName()) { + return $translation->getName(); + } + } + + return null; + } + + public function getProductListingPriceForChannel(ChannelInterface $channel): ?ListingPriceInterface + { + if (null !== $channel->getCode()) { + if ($this->productListingPrices->containsKey($channel->getCode())) { + return $this->productListingPrices->get($channel->getCode()); + } + } + + return null; + } + + /** @return Collection */ + public function getChannels(): Collection + { + return $this->channels; + } + + /** @param Collection $channels */ + public function setChannels(Collection $channels): void + { + $this->channels = $channels; + } + + public function addChannel(ChannelInterface $channel): void + { + $this->channels->add($channel); + } + + public function removeChannel(ChannelInterface $channel): void + { + $this->channels->removeElement($channel); + } + + public function isCreated(): bool + { + return self::STATUS_CREATED === $this->status; + } + + public function markAsCreated(): void + { + $this->status = self::STATUS_CREATED; + } + + public function ownRelations(): void + { + foreach ($this->getTranslations() as $translation) { + $translation->setProductDraft($this); + } + + foreach ($this->getAttributes() as $attribute) { + $attribute->setSubject($this); + } + + foreach ($this->getImages() as $image) { + $image->setOwner($this); + } + } + + public function getTaxCategory(): ?TaxCategoryInterface + { + return $this->taxCategory; + } + + public function setTaxCategory(?TaxCategoryInterface $category): void + { + $this->taxCategory = $category; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Entity/DraftAttribute.php b/OpenMarketplace/src/Component/ProductListing/Entity/DraftAttribute.php new file mode 100644 index 0000000..a67cda3 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Entity/DraftAttribute.php @@ -0,0 +1,56 @@ +productAttribute; + } + + public function setProductAttribute(?ProductAttributeInterface $productAttribute): void + { + $this->productAttribute = $productAttribute; + } + + public function getVendor(): VendorInterface + { + return $this->vendor; + } + + public function setVendor(VendorInterface $vendor): void + { + $this->vendor = $vendor; + } + + public function getUuid(): ?UuidInterface + { + return $this->uuid; + } + + public function setUuid(?UuidInterface $uuid): void + { + $this->uuid = $uuid; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Entity/DraftAttributeInterface.php b/OpenMarketplace/src/Component/ProductListing/Entity/DraftAttributeInterface.php new file mode 100644 index 0000000..4487f87 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Entity/DraftAttributeInterface.php @@ -0,0 +1,24 @@ +uuid; + } + + public function setUuid(?UuidInterface $uuid): void + { + $this->uuid = $uuid; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Entity/DraftAttributeTranslationInterface.php b/OpenMarketplace/src/Component/ProductListing/Entity/DraftAttributeTranslationInterface.php new file mode 100644 index 0000000..af49f1a --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Entity/DraftAttributeTranslationInterface.php @@ -0,0 +1,19 @@ +uuid; + } + + public function setUuid(?UuidInterface $uuid): void + { + $this->uuid = $uuid; + } + + public function getDraft(): ?DraftInterface + { + /** @var DraftInterface $subject */ + $subject = parent::getSubject(); + + return $subject; + } + + public function setDraft(?DraftInterface $product): void + { + parent::setSubject($product); + } + + public function setAttribute(?AttributeInterface $attribute): void + { + Assert::isInstanceOf($attribute, DraftAttributeInterface::class); + + $this->attribute = $attribute; + } + + /** @return DraftAttributeInterface|null */ + public function getAttribute(): ?AttributeInterface + { + if (null !== $this->attribute && !$this->attribute instanceof DraftAttributeInterface) { + throw new \InvalidArgumentException('Attribute must be instance of DraftAttributeInterface or null'); + } + + return $this->attribute; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Entity/DraftAttributeValueInterface.php b/OpenMarketplace/src/Component/ProductListing/Entity/DraftAttributeValueInterface.php new file mode 100644 index 0000000..14f1a17 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Entity/DraftAttributeValueInterface.php @@ -0,0 +1,30 @@ +uuid; + } + + public function setUuid(?UuidInterface $uuid): void + { + $this->uuid = $uuid; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Entity/DraftImageInterface.php b/OpenMarketplace/src/Component/ProductListing/Entity/DraftImageInterface.php new file mode 100644 index 0000000..30930a2 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Entity/DraftImageInterface.php @@ -0,0 +1,19 @@ + */ + public function getTranslations(): Collection; + + /** @param Collection $translations */ + public function setTranslations(Collection $translations): void; + + public function addTranslation(DraftTranslationInterface $translation): void; + + /** @return Collection */ + public function getProductListingPrices(): Collection; + + public function addProductListingPrice(ListingPriceInterface $productListingPrice): void; + + public function getProductListing(): ListingInterface; + + public function setProductListing(ListingInterface $productListing): void; + + public function getStatus(): string; + + public function setStatus(string $status): void; + + public function incrementVersion(): void; + + public function addTranslationWithKey(DraftTranslationInterface $translation, string $key): void; + + public function addProductListingPriceWithKey(ListingPriceInterface $productListingPrice, string $key): void; + + public function accept(): void; + + public function reject(): void; + + public function sendToVerification(): void; + + /** @return Collection $images */ + public function getImages(): Collection; + + /** @param Collection $images */ + public function setImages(Collection $images): void; + + public function addImage(ImageInterface $image): void; + + public function removeImage(ImageInterface $image): void; + + public function clearImages(): void; + + /** @return Collection */ + public function getAttributes(): Collection; + + /** @return Collection */ + public function getAttributesByLocale( + string $localeCode, + string $fallbackLocaleCode, + ?string $baseLocaleCode = null + ): Collection; + + public function addAttribute(AttributeValueInterface $attribute): void; + + public function removeAttribute(AttributeValueInterface $attribute): void; + + public function clearAttributes(): void; + + public function hasAttribute(AttributeValueInterface $attribute): bool; + + public function hasAttributeByCodeAndLocale(string $attributeCode, ?string $localeCode = null): bool; + + public function getAttributeByCodeAndLocale(string $attributeCode, ?string $localeCode = null): ?AttributeValueInterface; + + /** @return Collection */ + public function getProductDraftTaxons(): Collection; + + public function addProductDraftTaxon(DraftTaxonInterface $productDraftTaxons): void; + + public function removeProductDraftTaxon(DraftTaxonInterface $productDraftTaxons): void; + + public function clearProductDraftTaxons(): void; + + /** @return Collection */ + public function getTaxons(): Collection; + + public function hasTaxon(TaxonInterface $taxon): bool; + + public function getMainTaxon(): ?TaxonInterface; + + public function setMainTaxon(?TaxonInterface $mainTaxon): void; + + public function getName(string $locale): ?string; + + public function getSlug(string $locale): ?string; + + public function getVendor(): VendorInterface; + + public function getAnyTranslationName(): ?string; + + public function getProductListingPriceForChannel(ChannelInterface $channel): ?ListingPriceInterface; + + /** @return Collection */ + public function getChannels(): Collection; + + /** @param Collection $channels */ + public function setChannels(Collection $channels): void; + + public function addChannel(ChannelInterface $channel): void; + + public function removeChannel(ChannelInterface $channel): void; + + public function isCreated(): bool; + + public function markAsCreated(): void; + + public function ownRelations(): void; + + public function getTaxCategory(): ?TaxCategoryInterface; + + public function setTaxCategory(?TaxCategoryInterface $category): void; +} diff --git a/OpenMarketplace/src/Component/ProductListing/Entity/DraftTaxon.php b/OpenMarketplace/src/Component/ProductListing/Entity/DraftTaxon.php new file mode 100644 index 0000000..4e74347 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Entity/DraftTaxon.php @@ -0,0 +1,73 @@ +id; + } + + public function getUuid(): ?UuidInterface + { + return $this->uuid; + } + + public function setUuid(?UuidInterface $uuid): void + { + $this->uuid = $uuid; + } + + public function getProductDraft(): ?DraftInterface + { + return $this->productDraft; + } + + public function setProductDraft(?DraftInterface $productDraft): void + { + $this->productDraft = $productDraft; + } + + public function getTaxon(): ?TaxonInterface + { + return $this->taxon; + } + + public function setTaxon(?TaxonInterface $taxon): void + { + $this->taxon = $taxon; + } + + public function getPosition(): ?int + { + return $this->position; + } + + public function setPosition(?int $position): void + { + $this->position = $position; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Entity/DraftTaxonInterface.php b/OpenMarketplace/src/Component/ProductListing/Entity/DraftTaxonInterface.php new file mode 100644 index 0000000..15abe56 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Entity/DraftTaxonInterface.php @@ -0,0 +1,31 @@ +id; + } + + public function setId(int $id): void + { + $this->id = $id; + } + + public function getUuid(): ?UuidInterface + { + return $this->uuid; + } + + public function setUuid(?UuidInterface $uuid): void + { + $this->uuid = $uuid; + } + + public function getProductDraft(): DraftInterface + { + return $this->productDraft; + } + + public function setProductDraft(DraftInterface $productDraft): void + { + $this->productDraft = $productDraft; + } + + public function getName(): ?string + { + return $this->name; + } + + public function setName(?string $name): void + { + $this->name = $name; + } + + public function getSlug(): ?string + { + return $this->slug; + } + + public function setSlug(?string $slug): void + { + $this->slug = $slug; + } + + public function getDescription(): ?string + { + return $this->description; + } + + public function setDescription(?string $description): void + { + $this->description = $description; + } + + public function getMetaKeywords(): ?string + { + return $this->metaKeywords; + } + + public function setMetaKeywords(?string $metaKeywords): void + { + $this->metaKeywords = $metaKeywords; + } + + public function getMetaDescription(): ?string + { + return $this->metaDescription; + } + + public function setMetaDescription(?string $metaDescription): void + { + $this->metaDescription = $metaDescription; + } + + public function getShortDescription(): ?string + { + return $this->shortDescription; + } + + public function setShortDescription(?string $shortDescription): void + { + $this->shortDescription = $shortDescription; + } + + public function getLocale(): ?string + { + return $this->locale; + } + + public function setLocale(?string $locale): void + { + $this->locale = $locale; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Entity/DraftTranslationInterface.php b/OpenMarketplace/src/Component/ProductListing/Entity/DraftTranslationInterface.php new file mode 100644 index 0000000..7abc39f --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Entity/DraftTranslationInterface.php @@ -0,0 +1,53 @@ + */ + protected Collection $productDrafts; + + protected ?ProductInterface $product = null; + + protected ?DateTimeInterface $publishedAt = null; + + protected ?DateTimeInterface $lastVerifiedAt = null; + + protected DateTimeInterface $createdAt; + + public function __construct() + { + $this->productDrafts = new ArrayCollection(); + $this->createdAt = new \DateTime(); + } + + public function getId(): int + { + return $this->id; + } + + public function getUuid(): ?UuidInterface + { + return $this->uuid; + } + + public function setUuid(?UuidInterface $uuid): void + { + $this->uuid = $uuid; + } + + public function getCode(): ?string + { + return $this->code; + } + + public function setCode(?string $code): void + { + $this->code = $code; + } + + public function isEnabled(): bool + { + return $this->enabled; + } + + public function setEnabled(bool $enabled): void + { + $this->enabled = $enabled; + } + + public function setRemoved(bool $removed): void + { + $this->removed = $removed; + } + + public function isRemoved(): bool + { + return $this->removed; + } + + public function remove(): void + { + $this->removed = true; + } + + public function restore(): void + { + $this->removed = false; + } + + public function getVerificationStatus(): string + { + return $this->verificationStatus; + } + + public function setVerificationStatus(string $verificationStatus): void + { + $this->verificationStatus = $verificationStatus; + } + + public function getVendor(): VendorInterface + { + return $this->vendor; + } + + public function setVendor(VendorInterface $vendor): void + { + $this->vendor = $vendor; + } + + public function getLatestDraft(): ?DraftInterface + { + if (null === $this->latestDraft) { + $lastDraft = $this->getProductDrafts()->last(); + + return $lastDraft ?: null; + } + + return $this->latestDraft; + } + + public function getProductDrafts(): Collection + { + return $this->productDrafts; + } + + public function insertDraft(DraftInterface $newDraft): void + { + if (null !== $this->getLatestDraft()) { + $newDraft->setVersionNumber($this->getLatestDraft()->getVersionNumber()); + $newDraft->incrementVersion(); + } + + $newDraft->setProductListing($this); + + $this->productDrafts->add($newDraft); + + $this->latestDraft = $newDraft; + $this->verificationStatus = DraftInterface::STATUS_CREATED; + } + + public function getProduct(): ?ProductInterface + { + return $this->product; + } + + public function setProduct(?ProductInterface $product): void + { + $this->product = $product; + } + + public function getPublishedAt(): ?DateTimeInterface + { + return $this->publishedAt; + } + + public function setPublishedAt(DateTimeInterface $publishedAt): void + { + $this->publishedAt = $publishedAt; + } + + public function getLastVerifiedAt(): ?DateTimeInterface + { + return $this->lastVerifiedAt; + } + + public function setLastVerifiedAt(DateTimeInterface $lastVerifiedAt): void + { + $this->lastVerifiedAt = $lastVerifiedAt; + } + + public function getCreatedAt(): ?DateTimeInterface + { + return $this->createdAt; + } + + public function setCreatedAt(DateTimeInterface $createdAt): void + { + $this->createdAt = $createdAt; + } + + public function getAnyTranslationName(): ?string + { + $latestDraft = $this->getLatestDraft(); + + return $latestDraft?->getAnyTranslationName(); + } + + public function needsNewDraft(): bool + { + return null !== $this->getLatestDraft() && + false === $this->getLatestDraft()->isCreated(); + } + + public function canBeVerified(): bool + { + return null !== $this->getLatestDraft() && + DraftInterface::STATUS_CREATED === $this->getLatestDraft()->getStatus(); + } + + public function sendToVerification(DraftInterface $productDraft): void + { + $productDraft->sendToVerification(); + + $this->verificationStatus = $productDraft->getStatus(); + $this->publishedAt = $productDraft->getPublishedAt(); + } + + public function accept(): void + { + /** @var DraftInterface $latestDraft */ + $latestDraft = $this->getLatestDraft(); + Assert::isInstanceOf($latestDraft, DraftInterface::class); + + $latestDraft->accept(); + + $this->verificationStatus = $latestDraft->getStatus(); + $this->lastVerifiedAt = $latestDraft->getVerifiedAt(); + } + + public function reject(): void + { + /** @var DraftInterface $latestDraft */ + $latestDraft = $this->getLatestDraft(); + Assert::isInstanceOf($latestDraft, DraftInterface::class); + + $latestDraft->reject(); + + $this->verificationStatus = $latestDraft->getStatus(); + $this->lastVerifiedAt = $latestDraft->getVerifiedAt(); + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Entity/ListingInterface.php b/OpenMarketplace/src/Component/ProductListing/Entity/ListingInterface.php new file mode 100644 index 0000000..8f325cf --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Entity/ListingInterface.php @@ -0,0 +1,84 @@ + */ + public function getProductDrafts(): Collection; + + public function getProduct(): ?ProductInterface; + + public function setProduct(?ProductInterface $product): void; + + public function getPublishedAt(): ?DateTimeInterface; + + public function setPublishedAt(DatetimeInterface $publishedAt): void; + + public function getLastVerifiedAt(): ?DateTimeInterface; + + public function setLastVerifiedAt(DateTimeInterface $lastVerifiedAt): void; + + public function getCreatedAt(): ?DateTimeInterface; + + public function setCreatedAt(DatetimeInterface $createdAt): void; + + public function insertDraft(DraftInterface $newDraft): void; + + public function getAnyTranslationName(): ?string; + + public function getLatestDraft(): ?DraftInterface; + + public function needsNewDraft(): bool; + + public function canBeVerified(): bool; + + public function sendToVerification(DraftInterface $productDraft): void; + + public function accept(): void; + + public function reject(): void; +} diff --git a/OpenMarketplace/src/Component/ProductListing/Entity/ListingPrice.php b/OpenMarketplace/src/Component/ProductListing/Entity/ListingPrice.php new file mode 100644 index 0000000..8fc8565 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Entity/ListingPrice.php @@ -0,0 +1,101 @@ +id; + } + + public function setId(int $id): void + { + $this->id = $id; + } + + public function getUuid(): ?UuidInterface + { + return $this->uuid; + } + + public function setUuid(?UuidInterface $uuid): void + { + $this->uuid = $uuid; + } + + public function getProductDraft(): DraftInterface + { + return $this->productDraft; + } + + public function setProductDraft(DraftInterface $productDraft): void + { + $this->productDraft = $productDraft; + } + + public function getPrice(): ?int + { + return $this->price; + } + + public function setPrice(?int $price): void + { + $this->price = $price; + } + + public function getOriginalPrice(): ?int + { + return $this->originalPrice; + } + + public function setOriginalPrice(?int $originalPrice): void + { + $this->originalPrice = $originalPrice; + } + + public function getMinimumPrice(): int + { + return $this->minimumPrice; + } + + public function setMinimumPrice(int $minimumPrice): void + { + $this->minimumPrice = $minimumPrice; + } + + public function getChannelCode(): string + { + return $this->channelCode; + } + + public function setChannelCode(string $channelCode): void + { + $this->channelCode = $channelCode; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Entity/ListingPriceInterface.php b/OpenMarketplace/src/Component/ProductListing/Entity/ListingPriceInterface.php new file mode 100644 index 0000000..5ad7bb5 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Entity/ListingPriceInterface.php @@ -0,0 +1,42 @@ +productListingFactory->createNew(); + $productListing->setCode($productDraft->getCode()); + $productListing->insertDraft($productDraft); + $productListing->setVendor($vendor); + + $productDraft->setProductListing($productListing); + $productDraft->ownRelations(); + + $this->uploadImages($productDraft); + } + + public function resolveLatestDraft( + ListingInterface $listing + ): DraftInterface { + return $this->draftGenerator->generateNextDraft($listing); + } + + public function updateLatestDraftWith( + ListingInterface $listing, + DraftInterface $base + ): void { + $destination = $this->resolveLatestDraft($listing); + $this->draftCloner->clone($base, $destination); + $this->uploadImages($destination); + } + + public function uploadImages( + DraftInterface $productDraft + ): void { + foreach ($productDraft->getImages() as $image) { + $this->imageUploader->upload($image); + } + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/ListingPersisterInterface.php b/OpenMarketplace/src/Component/ProductListing/ListingPersisterInterface.php new file mode 100644 index 0000000..82b4ee5 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/ListingPersisterInterface.php @@ -0,0 +1,37 @@ +findVendorDraftAttributesQuery($vendor); + + return $queryBuilder + ->getQuery() + ->getResult() + ; + } + + public function findVendorDraftAttributesQuery(VendorInterface $vendor): QueryBuilder + { + $vendorId = $vendor->getId(); + + return $this->createQueryBuilder('o') + ->andWhere('o.vendor = :vendor') + ->setParameter('vendor', $vendorId) + ; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Repository/DraftAttributeRepositoryInterface.php b/OpenMarketplace/src/Component/ProductListing/Repository/DraftAttributeRepositoryInterface.php new file mode 100644 index 0000000..8164c3b --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Repository/DraftAttributeRepositoryInterface.php @@ -0,0 +1,20 @@ +_em->persist($productDraft); + $this->_em->flush(); + } + + public function findLatestDraft(ListingInterface $listing): ?DraftInterface + { + return $this->createQueryBuilder('pd') + ->andWhere('pd.productListing = :productListing') + ->setParameter('productListing', $listing) + ->orderBy('pd.id', 'desc') + ->setMaxResults(1) + ->getQuery() + ->getSingleResult() + ; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Repository/DraftRepositoryInterface.php b/OpenMarketplace/src/Component/ProductListing/Repository/DraftRepositoryInterface.php new file mode 100644 index 0000000..3180f01 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Repository/DraftRepositoryInterface.php @@ -0,0 +1,31 @@ +_em->persist($productTranslation); + $this->_em->flush(); + } + + public function saveCollection(array $productTranslations): void + { + foreach ($productTranslations as $productTranslation) { + $this->_em->persist($productTranslation); + } + + $this->_em->flush(); + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Repository/DraftTranslationRepositoryInterface.php b/OpenMarketplace/src/Component/ProductListing/Repository/DraftTranslationRepositoryInterface.php new file mode 100644 index 0000000..b85b860 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Repository/DraftTranslationRepositoryInterface.php @@ -0,0 +1,21 @@ +_em->persist($productListing); + $this->_em->flush(); + } + + public function createByProductDraftQueryBuilder(): QueryBuilder + { + return $this->createQueryBuilder('pl'); + } + + public function createQueryBuilderWithLatestDraft(): QueryBuilder + { + return $this->createQueryBuilder('pl') + ->innerJoin('pl.productDrafts', 'pd') + ->leftJoin('pl.productDrafts', 'pd2', 'WITH', 'pd.id < pd2.id') + ->andWhere('pd2 IS NULL') + ; + } + + public function createQueryBuilderByVendor(VendorInterface $vendor): QueryBuilder + { + $qb = $this->createQueryBuilderWithLatestDraft(); + $vendorId = $vendor->getId(); + + return $qb + ->andWhere('pl.vendor = :vendor') + ->setParameter('vendor', $vendorId) + ; + } + + public function createQueryBuilderByVendorAndDeleted(VendorInterface $vendor): QueryBuilder + { + $qb = $this->createQueryBuilderWithLatestDraft(); + $vendorId = $vendor->getId(); + + return $qb + ->andWhere('pl.vendor = :vendor') + ->andWhere('pl.removed = :notRemoved') + ->setParameter('notRemoved', false) + ->setParameter('vendor', $vendorId) + ; + } + + public function findByCodeAndVendor(DraftInterface $productDraft, VendorInterface $vendor): ?ListingInterface + { + $qb = $this->createCodeAndVendorQueryBuilder($productDraft, $vendor); + + return $qb->getQuery() + ->getOneOrNullResult() + ; + } + + public function findByCodeAndVendorOmitProductListing( + DraftInterface $productDraft, + VendorInterface $vendor, + ListingInterface $productListing + ): ?ListingInterface { + $qb = $this->createCodeAndVendorQueryBuilder($productDraft, $vendor); + + $qb->andWhere('pl.id != :id') + ->setParameter('id', $productListing->getId()) + ; + + return $qb->getQuery() + ->getOneOrNullResult() + ; + } + + private function createCodeAndVendorQueryBuilder(DraftInterface $productDraft, VendorInterface $vendor): QueryBuilder + { + return $this->createQueryBuilder('pl') + ->andWhere('pl.code = :code') + ->andWhere('pl.vendor = :vendor') + ->setParameter('code', $productDraft->getCode()) + ->setParameter('vendor', $vendor->getId()) + ; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Repository/ListingRepositoryInterface.php b/OpenMarketplace/src/Component/ProductListing/Repository/ListingRepositoryInterface.php new file mode 100644 index 0000000..1f22993 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Repository/ListingRepositoryInterface.php @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftAttribute.orm.xml b/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftAttribute.orm.xml new file mode 100644 index 0000000..5d8ab50 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftAttribute.orm.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftAttributeTranslation.orm.xml b/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftAttributeTranslation.orm.xml new file mode 100644 index 0000000..7ec66f2 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftAttributeTranslation.orm.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftAttributeValue.orm.xml b/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftAttributeValue.orm.xml new file mode 100644 index 0000000..c000f92 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftAttributeValue.orm.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftImage.orm.xml b/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftImage.orm.xml new file mode 100644 index 0000000..2ec83de --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftImage.orm.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftTaxon.orm.xml b/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftTaxon.orm.xml new file mode 100644 index 0000000..5d481bd --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftTaxon.orm.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftTranslation.orm.xml b/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftTranslation.orm.xml new file mode 100644 index 0000000..125f347 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/DraftTranslation.orm.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/Listing.orm.xml b/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/Listing.orm.xml new file mode 100644 index 0000000..9dc7f70 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/Listing.orm.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/ListingPrice.orm.xml b/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/ListingPrice.orm.xml new file mode 100644 index 0000000..f414996 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/doctrine/ListingPrice.orm.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/services.xml b/OpenMarketplace/src/Component/ProductListing/Resources/services.xml new file mode 100644 index 0000000..8436b45 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/services.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/services/draft_converter.xml b/OpenMarketplace/src/Component/ProductListing/Resources/services/draft_converter.xml new file mode 100644 index 0000000..f6f551b --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/services/draft_converter.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %sylius.uploader.filesystem% + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/services/draft_generator.xml b/OpenMarketplace/src/Component/ProductListing/Resources/services/draft_generator.xml new file mode 100644 index 0000000..4846ffd --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/services/draft_generator.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + %kernel.project_dir%/public/media/image + + + + + + + + + + + + + + + + + + + + + + + BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttribute + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/services/repositories.xml b/OpenMarketplace/src/Component/ProductListing/Resources/services/repositories.xml new file mode 100644 index 0000000..47166ab --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/services/repositories.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/services/validators.xml b/OpenMarketplace/src/Component/ProductListing/Resources/services/validators.xml new file mode 100644 index 0000000..e9e90f6 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/services/validators.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/validation/Draft.xml b/OpenMarketplace/src/Component/ProductListing/Resources/validation/Draft.xml new file mode 100644 index 0000000..a9f118c --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/validation/Draft.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/validation/DraftAttribute.xml b/OpenMarketplace/src/Component/ProductListing/Resources/validation/DraftAttribute.xml new file mode 100644 index 0000000..a021e03 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/validation/DraftAttribute.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/validation/DraftAttributeTranslation.xml b/OpenMarketplace/src/Component/ProductListing/Resources/validation/DraftAttributeTranslation.xml new file mode 100644 index 0000000..8377dc8 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/validation/DraftAttributeTranslation.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/validation/DraftTranslation.xml b/OpenMarketplace/src/Component/ProductListing/Resources/validation/DraftTranslation.xml new file mode 100644 index 0000000..f9e418d --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/validation/DraftTranslation.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Resources/validation/ListingPrice.xml b/OpenMarketplace/src/Component/ProductListing/Resources/validation/ListingPrice.xml new file mode 100644 index 0000000..26e7689 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Resources/validation/ListingPrice.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/ProductListing/Validator/Constraint/ProductListingCodeConstraint.php b/OpenMarketplace/src/Component/ProductListing/Validator/Constraint/ProductListingCodeConstraint.php new file mode 100644 index 0000000..e819a85 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Validator/Constraint/ProductListingCodeConstraint.php @@ -0,0 +1,31 @@ +service; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Validator/Constraint/ProductListingPriceConstraint.php b/OpenMarketplace/src/Component/ProductListing/Validator/Constraint/ProductListingPriceConstraint.php new file mode 100644 index 0000000..670c69a --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Validator/Constraint/ProductListingPriceConstraint.php @@ -0,0 +1,31 @@ +service; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Validator/Constraint/UniqueProductListingSlugConstraint.php b/OpenMarketplace/src/Component/ProductListing/Validator/Constraint/UniqueProductListingSlugConstraint.php new file mode 100644 index 0000000..840ee42 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Validator/Constraint/UniqueProductListingSlugConstraint.php @@ -0,0 +1,31 @@ +service; + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Validator/ProductListingCodeValidator.php b/OpenMarketplace/src/Component/ProductListing/Validator/ProductListingCodeValidator.php new file mode 100644 index 0000000..72b4848 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Validator/ProductListingCodeValidator.php @@ -0,0 +1,66 @@ +vendorContext->getVendor(); + if ($this->isCreatingNewProductListing()) { + $productListing = $this->productListingRepository->findByCodeAndVendor($value, $vendor); + } else { + $productListing = $this->productListingRepository->findByCodeAndVendorOmitProductListing($value, $vendor, $value->getProductListing()); + } + if (null !== $productListing) { + $this->context->addViolation($constraint->message); + } + } + + private function isCreatingNewProductListing(): bool + { + /** @var Request $request */ + $request = $this->requestStack->getCurrentRequest(); + + return + self::PRODUCT_LISTING_CREATE_PRODUCT_ROUTE + === $request->attributes->get('_route'); + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Validator/ProductListingPriceValidator.php b/OpenMarketplace/src/Component/ProductListing/Validator/ProductListingPriceValidator.php new file mode 100644 index 0000000..aa00597 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Validator/ProductListingPriceValidator.php @@ -0,0 +1,46 @@ +channelRepository->findAll(); + + foreach ($channels as $channel) { + /** @var ListingPriceInterface|null $productListingPrice */ + $productListingPrice = $value->getProductListingPriceForChannel($channel); + if (null === $productListingPrice || null === $productListingPrice->getPrice()) { + $this->context->addViolation($constraint->message); + + return; + } + } + } +} diff --git a/OpenMarketplace/src/Component/ProductListing/Validator/UniqueProductListingSlugValidator.php b/OpenMarketplace/src/Component/ProductListing/Validator/UniqueProductListingSlugValidator.php new file mode 100644 index 0000000..0af3207 --- /dev/null +++ b/OpenMarketplace/src/Component/ProductListing/Validator/UniqueProductListingSlugValidator.php @@ -0,0 +1,84 @@ +getSlug()); + if (0 === strlen($slug)) { + throw new UnexpectedTypeException($constraint, UniqueProductListingSlugConstraint::class); + } + + /** @var DraftTranslationInterface|null $existingProductTranslation */ + $existingProductTranslation = $this->productTranslationRepository->findOneBy(['slug' => $value->getSlug()]); + if (null === $existingProductTranslation) { + return; + } + + if ($this->isCreateListingProductPage()) { + $this->context->buildViolation($constraint->message) + ->atPath('slug') + ->setInvalidValue($value) + ->setCode(UniqueEntity::NOT_UNIQUE_ERROR) + ->addViolation() + ; + + return; + } + $currentProduct = $value->getProductDraft()?->getProductListing(); + + $existingProduct = $existingProductTranslation->getProductDraft()->getProductListing(); + + if (null !== $currentProduct) { + if ($currentProduct->getId() !== $existingProduct->getId()) { + $this->context->buildViolation($constraint->message) + ->atPath('slug') + ->setInvalidValue($value) + ->setCode(UniqueEntity::NOT_UNIQUE_ERROR) + ->addViolation() + ; + } + } + } + + private function isCreateListingProductPage(): bool + { + /** @var Request $request */ + $request = $this->requestStack->getCurrentRequest(); + + return self::PRODUCT_LISTING_CREATE_PRODUCT_ROUTE === $request->get('_route'); + } +} diff --git a/OpenMarketplace/src/Component/Settlement/Cli/SettlementGenerateCommand.php b/OpenMarketplace/src/Component/Settlement/Cli/SettlementGenerateCommand.php new file mode 100644 index 0000000..351b75c --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Cli/SettlementGenerateCommand.php @@ -0,0 +1,74 @@ +setName(self::COMMAND_NAME) + ->setDescription('Generates settlements for vendors'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $vendors = $this->vendorRepository->findAll(); + $channels = $this->channelRepository->findAllEnabled(); + + $persistCount = 0; + /** @var VendorInterface $vendor */ + foreach ($vendors as $vendor) { + $newSettlements = $this->settlementCreator->createSettlementsForAutoGeneration( + $vendor, + $channels, + ); + + if (0 === count($newSettlements)) { + continue; + } + + if (0 === ($persistCount % 50)) { + $this->settlementManager->flush(); + } + $persistCount += count($newSettlements); + + $this->settlementsCreatedEmailSender->send($vendor, $newSettlements); + } + + $this->settlementManager->flush(); + + return Command::SUCCESS; + } +} diff --git a/OpenMarketplace/src/Component/Settlement/Contracts/SettlementTransitions.php b/OpenMarketplace/src/Component/Settlement/Contracts/SettlementTransitions.php new file mode 100644 index 0000000..721f58c --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Contracts/SettlementTransitions.php @@ -0,0 +1,21 @@ +createCyclicalSettlements($vendor) + : $this->createNonCyclicalSettlements($vendor, $eventArgs) + ; + + return $settlements; + } + + private function createNonCyclicalSettlements(VendorInterface $vendor, PostUpdateEventArgs $eventArgs): array + { + $settlements = []; + $virtualWallets = $this->virtualWalletRepository->findAllByVendorWithPositiveBalance($vendor); + + /** @var VirtualWalletInterface $virtualWallet */ + foreach ($virtualWallets as $virtualWallet) { + $lastSettlement = $this->settlementRepository->findLastByVendorAndChannel($vendor, $virtualWallet->getChannel()); + + $compensatorySettlementFrom = $lastSettlement + ? (\DateTime::createFromInterface($lastSettlement->getEndDate()))->modify('+1 second') + : $vendor->getCreatedAt() + ; + + $compensatorySettlementTo = new \DateTime(); + + $total = $virtualWallet->getBalance(); + $settlement = $this->settlementFactory->createNewForVendorAndChannel( + $vendor, + $virtualWallet->getChannel(), + $total, + 0, + $compensatorySettlementFrom, + $compensatorySettlementTo, + ); + + $this->entityManager->persist($settlement); + + $this->virtualWalletManager->withdraw($settlement, $eventArgs); + + $settlements[] = $settlement; + } + + return $settlements; + } + + private function createCyclicalSettlements(VendorInterface $vendor): array + { + $channels = $this->channelRepository->findAll(); + $settlements = []; + + /** @var ChannelInterface $channel */ + foreach ($channels as $channel) { + $lastSettlement = $this->settlementRepository->findLastByVendorAndChannel($vendor, $channel); + + $compensatorySettlementFrom = $lastSettlement + ? (\DateTime::createFromInterface($lastSettlement->getEndDate()))->modify('+ 1 second') + : $vendor->getCreatedAt() + ; + + $compensatorySettlementTo = new \DateTime(); + + [ + 'total' => $total, + 'commissionTotal' => $commissionTotal + ] = $this->orderRepository->findForSettlementByVendorAndChannelAndDates( + $vendor, + $channel, + $compensatorySettlementFrom, + $compensatorySettlementTo, + ); + + if (0 === (int) $total && 0 === (int) $commissionTotal) { + continue; + } + + $settlement = $this->settlementFactory->createNewForVendorAndChannel( + $vendor, + $channel, + (int) $total, + (int) $commissionTotal, + $compensatorySettlementFrom, + $compensatorySettlementTo, + ); + + $this->entityManager->persist($settlement); + $settlements[] = $settlement; + } + + return $settlements; + } +} diff --git a/OpenMarketplace/src/Component/Settlement/Creator/CompensatorySettlementsCreatorInterface.php b/OpenMarketplace/src/Component/Settlement/Creator/CompensatorySettlementsCreatorInterface.php new file mode 100644 index 0000000..4b0a244 --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Creator/CompensatorySettlementsCreatorInterface.php @@ -0,0 +1,24 @@ +hasCyclicalSettlementFrequency()) { + return throw new \InvalidArgumentException( + sprintf('Could not find period resolver for vendor with settlement frequency "%s"', $vendor->getSettlementFrequency()) + ); + } + + $generatedSettlements = []; + + /** @var ChannelInterface $channel */ + foreach ($channels as $channel) { + $settlement = $this->createSettlementForVendorAndChannelIfNotExists( + $vendor, + $channel, + ); + + if (!$settlement instanceof SettlementInterface) { + continue; + } + + $this->settlementManager->persist($settlement); + + $generatedSettlements[] = $settlement; + } + + return $generatedSettlements; + } + + public function createSettlementForWithdrawal( + VendorInterface $vendor, + ChannelInterface $channel, + int $amount, + ): SettlementInterface { + $lastSettlement = $this->settlementRepository->findLastByVendorAndChannel($vendor, $channel); + + [$nextSettlementStartDate, $nextSettlementEndDate] = $this->settlementPeriodResolver->getSettlementDateRangeForVendor( + $vendor, + false, + !$lastSettlement ? null : $lastSettlement->getEndDate() + ); + + $settlement = $this->settlementFactory->createNewForVendorAndChannel( + $vendor, + $channel, + $amount, + 0, + $nextSettlementStartDate, + $nextSettlementEndDate + ); + + $this->settlementManager->persist($settlement); + + return $settlement; + } + + private function createSettlementForVendorAndChannelIfNotExists( + VendorInterface $vendor, + ChannelInterface $channel + ): ?SettlementInterface { + $lastSettlement = $this->settlementRepository->findLastByVendorAndChannel($vendor, $channel); + + [$nextSettlementStartDate, $nextSettlementEndDate] = $this->settlementPeriodResolver->getSettlementDateRangeForVendor( + $vendor, + true, + !$lastSettlement ? null : $lastSettlement->getEndDate() + ); + + if ( + null !== $lastSettlement + && $lastSettlement->getEndDate() > $nextSettlementStartDate + ) { + return null; + } + + [ + 'total' => $total, + 'commissionTotal' => $commissionTotal + ] = $this->orderRepository->findForSettlementByVendorAndChannelAndDates( + $vendor, + $channel, + $nextSettlementStartDate, + $nextSettlementEndDate + ); + + return $this->settlementFactory->createNewForVendorAndChannel( + $vendor, + $channel, + (int) $total, + (int) $commissionTotal, + $nextSettlementStartDate, + $nextSettlementEndDate + ); + } +} diff --git a/OpenMarketplace/src/Component/Settlement/Creator/SettlementCreatorInterface.php b/OpenMarketplace/src/Component/Settlement/Creator/SettlementCreatorInterface.php new file mode 100644 index 0000000..3218c15 --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Creator/SettlementCreatorInterface.php @@ -0,0 +1,30 @@ +virtualWalletRepository->findByVendorAndChannel($vendor, $channel); + + if (null !== $virtualWallet) { + return $virtualWallet; + } + + return $this->virtualWalletFactory->createForVendorAndChannel($vendor, $channel); + } +} diff --git a/OpenMarketplace/src/Component/Settlement/Creator/VirtualWalletCreatorInterface.php b/OpenMarketplace/src/Component/Settlement/Creator/VirtualWalletCreatorInterface.php new file mode 100644 index 0000000..7f41a93 --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Creator/VirtualWalletCreatorInterface.php @@ -0,0 +1,24 @@ +id; + } + + public function getVendor(): VendorInterface + { + return $this->vendor; + } + + public function setVendor(VendorInterface $vendor): void + { + $this->vendor = $vendor; + } + + public function getStatus(): string + { + return $this->status; + } + + public function setStatus(string $status): void + { + $this->status = $status; + } + + public function getTotalAmount(): int + { + return $this->totalAmount; + } + + public function setTotalAmount(int $totalAmount): void + { + $this->totalAmount = $totalAmount; + } + + public function getTotalCommissionAmount(): int + { + return $this->totalCommissionAmount; + } + + public function setTotalCommissionAmount(int $totalCommissionAmount): void + { + $this->totalCommissionAmount = $totalCommissionAmount; + } + + public function getTotalProfitAmount(): int + { + return $this->totalAmount - $this->totalCommissionAmount; + } + + public function getStartDate(): \DateTimeInterface + { + return $this->startDate; + } + + public function setStartDate(\DateTimeInterface $startDate): void + { + $this->startDate = $startDate; + } + + public function getEndDate(): \DateTimeInterface + { + return $this->endDate; + } + + public function setEndDate(\DateTimeInterface $endDate): void + { + $this->endDate = $endDate; + } + + public function getChannel(): ChannelInterface + { + return $this->channel; + } + + public function setChannel(ChannelInterface $channel): void + { + $this->channel = $channel; + } +} diff --git a/OpenMarketplace/src/Component/Settlement/Entity/SettlementInterface.php b/OpenMarketplace/src/Component/Settlement/Entity/SettlementInterface.php new file mode 100644 index 0000000..b500e7c --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Entity/SettlementInterface.php @@ -0,0 +1,64 @@ +balance = 0; + } + + public function getId(): ?int + { + return $this->id; + } + + public function getVendor(): VendorInterface + { + return $this->vendor; + } + + public function setVendor(VendorInterface $vendor): void + { + $this->vendor = $vendor; + } + + public function getBalance(): int + { + return $this->balance; + } + + public function getChannel(): ChannelInterface + { + return $this->channel; + } + + public function setChannel(ChannelInterface $channel): void + { + $this->channel = $channel; + } + + public function stash(OrderInterface $order): void + { + $this->balance += $order->getTotalProfitAmount(); + } + + public function withdraw(SettlementInterface $settlement): void + { + if ($this->balance < $settlement->getTotalProfitAmount()) { + throw new NotEnoughFundsException('Not enough funds to withdraw'); + } + + $this->balance -= $settlement->getTotalProfitAmount(); + } +} diff --git a/OpenMarketplace/src/Component/Settlement/Entity/VirtualWalletInterface.php b/OpenMarketplace/src/Component/Settlement/Entity/VirtualWalletInterface.php new file mode 100644 index 0000000..956ec5f --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Entity/VirtualWalletInterface.php @@ -0,0 +1,34 @@ +createNew(); + $settlement->setVendor($vendor); + $settlement->setChannel($channel); + $settlement->setStartDate($nextSettlementStartDate); + $settlement->setEndDate($nextSettlementEndDate); + $settlement->setTotalAmount($total); + $settlement->setTotalCommissionAmount($commissionTotal); + + return $settlement; + } +} diff --git a/OpenMarketplace/src/Component/Settlement/Factory/SettlementFactoryInterface.php b/OpenMarketplace/src/Component/Settlement/Factory/SettlementFactoryInterface.php new file mode 100644 index 0000000..830afd9 --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Factory/SettlementFactoryInterface.php @@ -0,0 +1,29 @@ +createNew(); + $virtualWallet->setVendor($vendor); + $virtualWallet->setChannel($channel); + + return $virtualWallet; + } +} diff --git a/OpenMarketplace/src/Component/Settlement/Factory/VirtualWalletFactoryInterface.php b/OpenMarketplace/src/Component/Settlement/Factory/VirtualWalletFactoryInterface.php new file mode 100644 index 0000000..bab201a --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Factory/VirtualWalletFactoryInterface.php @@ -0,0 +1,27 @@ +getVendor(); + + if (!$vendor instanceof VendorInterface) { + return; + } + + $channel = $order->getChannel(); + Assert::isInstanceOf($channel, ChannelInterface::class); + + if (!$this->supportsWalletOperations($vendor)) { + return; + } + + $virtualWallet = $this->virtualWalletCreator->createForVendorAndChannel($vendor, $channel); + $virtualWallet->stash($order); + + $this->entityManager->persist($virtualWallet); + } + + public function withdraw(SettlementInterface $settlement, PostUpdateEventArgs $eventArgs = null): void + { + $vendor = $settlement->getVendor(); + $channel = $settlement->getChannel(); + + if (!$this->supportsWalletOperations($vendor, $eventArgs)) { + return; + } + + $virtualWallet = $this->virtualWalletCreator->createForVendorAndChannel($vendor, $channel); + $virtualWallet->withdraw($settlement); + + $this->entityManager->persist($virtualWallet); + } + + private function supportsWalletOperations(VendorInterface $vendor, PostUpdateEventArgs $eventArgs = null): bool + { + $supportsWalletOperation = VendorSettlementFrequency::VIRTUAL_WALLET === $vendor->getSettlementFrequency(); + + if ($supportsWalletOperation || null === $eventArgs) { + return $supportsWalletOperation; + } + + $vendor = $eventArgs->getObject(); + if (!$vendor instanceof VendorInterface) { + return false; + } + + $objectManager = $eventArgs->getObjectManager(); + $unitOfWork = $objectManager->getUnitOfWork(); + $changeSet = $unitOfWork->getEntityChangeSet($vendor); + + if (!array_key_exists(VendorListener::SETTLEMENT_FREQUENCY, $changeSet)) { + return false; + } + + $vendorChangeSet = $changeSet[VendorListener::SETTLEMENT_FREQUENCY]; + $previousFrequency = $vendorChangeSet[0]; + + return VendorSettlementFrequency::VIRTUAL_WALLET === $previousFrequency; + } +} diff --git a/OpenMarketplace/src/Component/Settlement/Manager/VirtualWalletManagerInterface.php b/OpenMarketplace/src/Component/Settlement/Manager/VirtualWalletManagerInterface.php new file mode 100644 index 0000000..9b0a0a9 --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Manager/VirtualWalletManagerInterface.php @@ -0,0 +1,23 @@ +getSettlementFrequency() === $this->getSettlementFrequency() && + $this->checkSupportsFrequencyType($cyclical) + ; + } + + protected function checkSupportsFrequencyType(bool $cyclical): bool + { + return $cyclical === in_array( + $this->getSettlementFrequency(), + VendorSettlementFrequency::CYCLICAL_SETTLEMENT_FREQUENCIES, + true + ); + } + + abstract public function resolve(?\DateTimeInterface $lastSettlementEndsAt): array; + + abstract public function getSettlementFrequency(): string; +} diff --git a/OpenMarketplace/src/Component/Settlement/PeriodStrategy/MonthlySettlementPeriodResolver.php b/OpenMarketplace/src/Component/Settlement/PeriodStrategy/MonthlySettlementPeriodResolver.php new file mode 100644 index 0000000..731ec56 --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/PeriodStrategy/MonthlySettlementPeriodResolver.php @@ -0,0 +1,32 @@ +setTimestamp(self::getLastQuarterStartDate()), + (new \DateTime())->setTimestamp(self::getLastQuarterEndDate()), + ]; + } + + public function getSettlementFrequency(): string + { + return self::SETTLEMENT_FREQUENCY; + } + + public static function getLastQuarterStartDate(): int + { + $month = date('n'); + $countLastQuarterEndMonthAgo = (int) abs(((ceil($month / 3) - 1) * 3) - $month); + + $dateTime = mktime( + 00, + 00, + 00, + $month - $countLastQuarterEndMonthAgo - 2, + 1, + (int) date('Y') + ); + + if (false === $dateTime) { + throw new \RuntimeException('Cannot generate last quarter start date'); + } + + return $dateTime; + } + + public static function getLastQuarterEndDate(): int + { + $month = date('n'); + $countLastQuarterEndMonthAgo = (int) abs(((ceil($month / 3) - 1) * 3) - $month); + + $dateTime = mktime( + 23, + 59, + 59, + $month - $countLastQuarterEndMonthAgo + 1, + 0, + (int) date('Y') + ); + if (false === $dateTime) { + throw new \RuntimeException('Cannot generate last quarter end date'); + } + + return $dateTime; + } +} diff --git a/OpenMarketplace/src/Component/Settlement/PeriodStrategy/SettlementPeriodResolver.php b/OpenMarketplace/src/Component/Settlement/PeriodStrategy/SettlementPeriodResolver.php new file mode 100644 index 0000000..ae637fe --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/PeriodStrategy/SettlementPeriodResolver.php @@ -0,0 +1,62 @@ +settlementPeriodResolvers as $settlementPeriodResolver) { + if (!$settlementPeriodResolver->supports($vendor, $cyclical)) { + continue; + } + + $vendorCreatedAt = $vendor->getCreatedAt(); + + [$from, $to] = $settlementPeriodResolver->resolve($lastSettlementEndsAt ?? $vendorCreatedAt); + + return [ + $this->getFrom($from, $to, $lastSettlementEndsAt), + $to, + ]; + } + + throw new \InvalidArgumentException(sprintf('Could not find period resolver for vendor with settlement frequency "%s"', $vendor->getSettlementFrequency())); + } + + private function getFrom( + \DateTime $from, + \DateTime $to, + ?\DateTimeInterface $lastSettlementEndsAt + ): \DateTime { + if ( + null === $lastSettlementEndsAt + || ($from >= $lastSettlementEndsAt + || $to <= $lastSettlementEndsAt) + ) { + return $from; + } + + return \DateTime::createFromInterface($lastSettlementEndsAt)->modify('+1 second'); + } +} diff --git a/OpenMarketplace/src/Component/Settlement/PeriodStrategy/SettlementPeriodResolverInterface.php b/OpenMarketplace/src/Component/Settlement/PeriodStrategy/SettlementPeriodResolverInterface.php new file mode 100644 index 0000000..9274535 --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/PeriodStrategy/SettlementPeriodResolverInterface.php @@ -0,0 +1,23 @@ +modify('+1 second'), + new \DateTime(), + ]; + } + + public function getSettlementFrequency(): string + { + return self::SETTLEMENT_FREQUENCY; + } +} diff --git a/OpenMarketplace/src/Component/Settlement/PeriodStrategy/WeeklySettlementPeriodResolver.php b/OpenMarketplace/src/Component/Settlement/PeriodStrategy/WeeklySettlementPeriodResolver.php new file mode 100644 index 0000000..e2eaefd --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/PeriodStrategy/WeeklySettlementPeriodResolver.php @@ -0,0 +1,32 @@ +createQueryBuilder('s') + ->andWhere('s.vendor = :vendorId') + ->andWhere('s.channel = :channelId') + ->setParameter('vendorId', $vendor->getId()) + ->setParameter('channelId', $channel->getId()) + ->orderBy('s.endDate', self::ORDER_DESCENDING) + ->setMaxResults(1) + ->getQuery() + ->getOneOrNullResult(); + } + + public function findAllPeriods(): array + { + return $this->createQueryBuilder('s') + ->distinct(true) + ->select( + 'CONCAT( + DATE_FORMAT(s.startDate, \'%e/%m/%Y\'), + \' - \', + DATE_FORMAT(s.endDate, \'%e/%m/%Y\') + ) as period' + ) + ->orderBy('period', self::ORDER_DESCENDING) + ->getQuery() + ->getSingleColumnResult() + ; + } + + public function findAllByVendorQueryBuilder(VendorInterface $vendor): QueryBuilder + { + $result = $this->createQueryBuilder('s') + ->andWhere('s.vendor = :vendor') + ->setParameter('vendor', $vendor) + ->orderBy('s.createdAt', self::ORDER_DESCENDING); + + return $result; + } +} diff --git a/OpenMarketplace/src/Component/Settlement/Repository/SettlementRepositoryInterface.php b/OpenMarketplace/src/Component/Settlement/Repository/SettlementRepositoryInterface.php new file mode 100644 index 0000000..66ac639 --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Repository/SettlementRepositoryInterface.php @@ -0,0 +1,27 @@ +createQueryBuilder('wv') + ->andWhere('wv.vendor = :vendor') + ->andWhere('wv.channel = :channel') + ->setParameter('vendor', $vendor) + ->setParameter('channel', $channel) + ->getQuery() + ->getOneOrNullResult() + ; + } + + public function findAllByVendorQueryBuilder(VendorInterface $vendor): QueryBuilder + { + $queryBuilder = $this->createQueryBuilder('wv') + ->andWhere('wv.vendor = :vendor') + ->setParameter('vendor', $vendor); + + return $queryBuilder; + } + + public function findAllByVendorWithPositiveBalance(VendorInterface $vendor): array + { + return $this->findAllByVendorQueryBuilder($vendor) + ->andWhere('wv.balance > 0') + ->orderBy('wv.id', self::ORDER_DESCENDING) + ->getQuery() + ->getResult() + ; + } +} diff --git a/OpenMarketplace/src/Component/Settlement/Repository/VirtualWalletRepositoryInterface.php b/OpenMarketplace/src/Component/Settlement/Repository/VirtualWalletRepositoryInterface.php new file mode 100644 index 0000000..f02b6d1 --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Repository/VirtualWalletRepositoryInterface.php @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Settlement/Resources/doctrine/VirtualWallet.orm.xml b/OpenMarketplace/src/Component/Settlement/Resources/doctrine/VirtualWallet.orm.xml new file mode 100644 index 0000000..021961a --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Resources/doctrine/VirtualWallet.orm.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Settlement/Resources/services.xml b/OpenMarketplace/src/Component/Settlement/Resources/services.xml new file mode 100644 index 0000000..3e59788 --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Resources/services.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Settlement/Resources/services/cli.xml b/OpenMarketplace/src/Component/Settlement/Resources/services/cli.xml new file mode 100644 index 0000000..c20982f --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Resources/services/cli.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Settlement/Resources/services/creator.xml b/OpenMarketplace/src/Component/Settlement/Resources/services/creator.xml new file mode 100644 index 0000000..0329aa9 --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Resources/services/creator.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Settlement/Resources/services/manager.xml b/OpenMarketplace/src/Component/Settlement/Resources/services/manager.xml new file mode 100644 index 0000000..c208a05 --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Resources/services/manager.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Settlement/Resources/services/period_strategy.xml b/OpenMarketplace/src/Component/Settlement/Resources/services/period_strategy.xml new file mode 100644 index 0000000..5995701 --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Resources/services/period_strategy.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Settlement/Resources/services/sender.xml b/OpenMarketplace/src/Component/Settlement/Resources/services/sender.xml new file mode 100644 index 0000000..de079a0 --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Resources/services/sender.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Settlement/Resources/services/twig.xml b/OpenMarketplace/src/Component/Settlement/Resources/services/twig.xml new file mode 100644 index 0000000..85975d6 --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Resources/services/twig.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Settlement/Sender/SettlementsCreatedEmailSender.php b/OpenMarketplace/src/Component/Settlement/Sender/SettlementsCreatedEmailSender.php new file mode 100644 index 0000000..caf500b --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Sender/SettlementsCreatedEmailSender.php @@ -0,0 +1,79 @@ +getShopUser(); + + try { + /** + * Deprecated: + * using this method without 2 last arguments ($ccRecipients and $bccRecipients) + * is deprecated since 1.8 and won't be possible since 2.0 + * + * We don't need to define these arguments as for now but we will have to provide them in the future. + * We can ignore checking this line and remove it when method signature changes. + */ + /** + * @phpstan-ignore-next-line + */ + $this->sender->send( + self::EMAIL_TEMPLATE, + [$shopUser->getEmail()], + [ + 'settlements' => $this->mapSettlements($settlements), + ], + [], + [], + [], + [], + ); + } catch (\Exception $exception) { + $this->logger->error( + sprintf( + 'An exception occurred while sending settlement created email for vendor with id %s: %s', + $vendor->getId(), + $exception->getMessage() + ) + ); + } + } + + private function mapSettlements(array $settlements): array + { + return array_map( + fn (SettlementInterface $settlement) => [ + 'startDate' => $settlement->getStartDate(), + 'endDate' => $settlement->getEndDate(), + 'commissionTotal' => $settlement->getTotalCommissionAmount(), + 'channelName' => $settlement->getChannel()->getName(), + ], + $settlements + ); + } +} diff --git a/OpenMarketplace/src/Component/Settlement/Sender/SettlementsCreatedEmailSenderInterface.php b/OpenMarketplace/src/Component/Settlement/Sender/SettlementsCreatedEmailSenderInterface.php new file mode 100644 index 0000000..075ad68 --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Sender/SettlementsCreatedEmailSenderInterface.php @@ -0,0 +1,19 @@ +vendorContext->getVendor(); + Assert::isInstanceOf($vendor, VendorInterface::class); + + $virtualWallet = $this->virtualWalletRepository->findByVendorAndChannel($vendor, $channel); + + return $virtualWallet ? $virtualWallet->getBalance() : 0; + } +} diff --git a/OpenMarketplace/src/Component/Settlement/Twig/Runtime/VirtualWalletBalanceRuntimeInterface.php b/OpenMarketplace/src/Component/Settlement/Twig/Runtime/VirtualWalletBalanceRuntimeInterface.php new file mode 100644 index 0000000..a02629d --- /dev/null +++ b/OpenMarketplace/src/Component/Settlement/Twig/Runtime/VirtualWalletBalanceRuntimeInterface.php @@ -0,0 +1,19 @@ +id; + } + + public function getCountry(): ?CountryInterface + { + return $this->country; + } + + public function setCountry(?CountryInterface $country): void + { + $this->country = $country; + } + + public function getCity(): ?string + { + return $this->city; + } + + public function setCity(?string $city): void + { + $this->city = $city; + } + + public function getStreet(): ?string + { + return $this->street; + } + + public function setStreet(?string $street): void + { + $this->street = $street; + } + + public function getPostalCode(): ?string + { + return $this->postalCode; + } + + public function setPostalCode(?string $postalCode): void + { + $this->postalCode = $postalCode; + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Entity/AddressInterface.php b/OpenMarketplace/src/Component/Vendor/Entity/AddressInterface.php new file mode 100644 index 0000000..2c1ae3d --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Entity/AddressInterface.php @@ -0,0 +1,36 @@ +id; + } + + public function getUuid(): ?UuidInterface + { + return $this->uuid; + } + + public function setUuid(?UuidInterface $uuid): void + { + $this->uuid = $uuid; + } + + public function getFile(): ?\SplFileInfo + { + return $this->file; + } + + public function setFile(?\SplFileInfo $file): void + { + $this->file = $file; + } + + public function hasFile(): bool + { + return null !== $this->file; + } + + public function getPath(): ?string + { + return $this->path; + } + + public function setPath(?string $path): void + { + $this->path = $path; + } + + /** @return object|null */ + public function getOwner(): ?object + { + return $this->owner; + } + + /** @param object|null $owner */ + public function setOwner($owner): void + { + $this->owner = $owner; + } + + public function getType(): ?string + { + return 'background'; + } + + public function setType(?string $type): void + { + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Entity/BackgroundImageInterface.php b/OpenMarketplace/src/Component/Vendor/Entity/BackgroundImageInterface.php new file mode 100644 index 0000000..01b82f1 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Entity/BackgroundImageInterface.php @@ -0,0 +1,34 @@ +id; + } + + public function getUuid(): ?UuidInterface + { + return $this->uuid; + } + + public function setUuid(?UuidInterface $uuid): void + { + $this->uuid = $uuid; + } + + public function getFile(): ?\SplFileInfo + { + return $this->file; + } + + public function setFile(?\SplFileInfo $file): void + { + $this->file = $file; + } + + public function hasFile(): bool + { + return null !== $this->file; + } + + public function getPath(): ?string + { + return $this->path; + } + + public function setPath(?string $path): void + { + $this->path = $path; + } + + /** @return object|null */ + public function getOwner(): ?object + { + return $this->owner; + } + + /** @param object|null $owner */ + public function setOwner($owner): void + { + $this->owner = $owner; + } + + public function getType(): ?string + { + return 'avatar'; + } + + public function setType(?string $type): void + { + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Entity/LogoImageInterface.php b/OpenMarketplace/src/Component/Vendor/Entity/LogoImageInterface.php new file mode 100644 index 0000000..0053504 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Entity/LogoImageInterface.php @@ -0,0 +1,34 @@ +id; + } + + public function getCountry(): ?CountryInterface + { + return $this->country; + } + + public function setCountry(?CountryInterface $country): void + { + $this->country = $country; + } + + public function getCity(): ?string + { + return $this->city; + } + + public function setCity(?string $city): void + { + $this->city = $city; + } + + public function getStreet(): ?string + { + return $this->street; + } + + public function setStreet(?string $street): void + { + $this->street = $street; + } + + public function getPostalCode(): ?string + { + return $this->postalCode; + } + + public function setPostalCode(?string $postalCode): void + { + $this->postalCode = $postalCode; + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Entity/ProfileUpdate/BackgroundImage.php b/OpenMarketplace/src/Component/Vendor/Entity/ProfileUpdate/BackgroundImage.php new file mode 100644 index 0000000..d6f45f1 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Entity/ProfileUpdate/BackgroundImage.php @@ -0,0 +1,74 @@ +id; + } + + public function getFile(): ?\SplFileInfo + { + return $this->file; + } + + public function setFile(?\SplFileInfo $file): void + { + $this->file = $file; + } + + public function hasFile(): bool + { + return null !== $this->file; + } + + public function getPath(): ?string + { + return $this->path; + } + + public function setPath(?string $path): void + { + $this->path = $path; + } + + public function getOwner(): ?object + { + return $this->owner; + } + + public function setOwner($owner): void + { + $this->owner = $owner; + } + + public function getType(): ?string + { + return 'background'; + } + + public function setType(?string $type): void + { + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Entity/ProfileUpdate/LogoImage.php b/OpenMarketplace/src/Component/Vendor/Entity/ProfileUpdate/LogoImage.php new file mode 100644 index 0000000..158b8c4 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Entity/ProfileUpdate/LogoImage.php @@ -0,0 +1,74 @@ +id; + } + + public function getFile(): ?\SplFileInfo + { + return $this->file; + } + + public function setFile(?\SplFileInfo $file): void + { + $this->file = $file; + } + + public function hasFile(): bool + { + return null !== $this->file; + } + + public function getPath(): ?string + { + return $this->path; + } + + public function setPath(?string $path): void + { + $this->path = $path; + } + + public function getOwner(): ?object + { + return $this->owner; + } + + public function setOwner($owner): void + { + $this->owner = $owner; + } + + public function getType(): ?string + { + return 'image'; + } + + public function setType(?string $type): void + { + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Entity/ProfileUpdate/ProfileUpdate.php b/OpenMarketplace/src/Component/Vendor/Entity/ProfileUpdate/ProfileUpdate.php new file mode 100644 index 0000000..a5c5d8a --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Entity/ProfileUpdate/ProfileUpdate.php @@ -0,0 +1,152 @@ +id; + } + + public function setId(int $id): void + { + $this->id = $id; + } + + public function getVendor(): VendorInterface + { + return $this->vendor; + } + + public function setVendor(VendorInterface $vendor): void + { + $this->vendor = $vendor; + } + + public function getCompanyName(): ?string + { + return $this->companyName; + } + + public function setCompanyName(?string $companyName): void + { + $this->companyName = $companyName; + } + + public function getTaxIdentifier(): ?string + { + return $this->taxIdentifier; + } + + public function setTaxIdentifier(?string $taxIdentifier): void + { + $this->taxIdentifier = $taxIdentifier; + } + + public function getBankAccountNumber(): ?string + { + return $this->bankAccountNumber; + } + + public function setBankAccountNumber(?string $bankAccountNumber): void + { + $this->bankAccountNumber = $bankAccountNumber; + } + + public function getPhoneNumber(): ?string + { + return $this->phoneNumber; + } + + public function setPhoneNumber(?string $phoneNumber): void + { + $this->phoneNumber = $phoneNumber; + } + + public function getVendorAddress(): ?AddressInterface + { + return $this->vendorAddress; + } + + public function setVendorAddress(?AddressInterface $vendorAddress): void + { + $this->vendorAddress = $vendorAddress; + } + + public function getToken(): ?string + { + return $this->token; + } + + public function setToken(?string $token): void + { + $this->token = $token; + } + + public function getDescription(): ?string + { + return $this->description; + } + + public function setDescription(?string $description): void + { + $this->description = $description; + } + + public function getImage(): ?LogoImageInterface + { + return $this->image; + } + + public function setImage(?LogoImageInterface $image): void + { + $this->image = $image; + } + + public function getBackgroundImage(): ?BackgroundImageInterface + { + return $this->backgroundImage; + } + + public function setBackgroundImage(?BackgroundImageInterface $backgroundImage): void + { + $this->backgroundImage = $backgroundImage; + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Entity/ProfileUpdate/ProfileUpdateInterface.php b/OpenMarketplace/src/Component/Vendor/Entity/ProfileUpdate/ProfileUpdateInterface.php new file mode 100644 index 0000000..fc96317 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Entity/ProfileUpdate/ProfileUpdateInterface.php @@ -0,0 +1,36 @@ +roles; + + $vendor = $this->getVendor(); + if (null !== $vendor && $vendor->isVerified() && $vendor->isEnabled()) { + $roles[] = self::ROLE_VENDOR; + } + + return array_unique($roles); + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Entity/ShopUserInterface.php b/OpenMarketplace/src/Component/Vendor/Entity/ShopUserInterface.php new file mode 100644 index 0000000..00d6b30 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Entity/ShopUserInterface.php @@ -0,0 +1,21 @@ +vendor; + } + + public function setVendor(VendorInterface $vendor): void + { + $this->vendor = $vendor; + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Entity/Vendor.php b/OpenMarketplace/src/Component/Vendor/Entity/Vendor.php new file mode 100644 index 0000000..20ffbcc --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Entity/Vendor.php @@ -0,0 +1,404 @@ + */ + protected Collection $products; + + /** @var Collection */ + protected Collection $productListings; + + /** @var Collection */ + protected Collection $shippingMethods; + + /** @var Collection */ + protected Collection $settlements; + + protected ?int $commission = 0; + + protected string $commissionType = self::NET_COMMISSION; + + protected string $settlementFrequency = VendorSettlementFrequency::DEFAULT_SETTLEMENT_FREQUENCY; + + public function __construct() + { + $this->products = new ArrayCollection(); + $this->shippingMethods = new ArrayCollection(); + $this->settlements = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function setId(?int $id): void + { + $this->id = $id; + } + + public function getUuid(): ?UuidInterface + { + return $this->uuid; + } + + public function setUuid(?UuidInterface $uuid): void + { + $this->uuid = $uuid; + } + + public function getCompanyName(): ?string + { + return $this->companyName; + } + + public function setCompanyName(?string $companyName): void + { + $this->companyName = $companyName; + } + + public function getTaxIdentifier(): ?string + { + return $this->taxIdentifier; + } + + public function setTaxIdentifier(?string $taxIdentifier): void + { + $this->taxIdentifier = $taxIdentifier; + } + + public function getBankAccountNumber(): ?string + { + return $this->bankAccountNumber; + } + + public function setBankAccountNumber(?string $bankAccountNumber): void + { + $this->bankAccountNumber = $bankAccountNumber; + } + + public function getPhoneNumber(): ?string + { + return $this->phoneNumber; + } + + public function setPhoneNumber(?string $phoneNumber): void + { + $this->phoneNumber = $phoneNumber; + } + + public function getVendorAddress(): ?AddressInterface + { + return $this->vendorAddress; + } + + public function setVendorAddress(?AddressInterface $vendorAddress): void + { + $this->vendorAddress = $vendorAddress; + } + + public function getShopUser(): ShopUserInterface + { + return $this->shopUser; + } + + public function setShopUser(ShopUserInterface $user): void + { + $this->shopUser = $user; + } + + public function getStatus(): string + { + return $this->status; + } + + public function setStatus(string $status): void + { + $this->status = $status; + } + + public function isEnabled(): bool + { + return $this->enabled; + } + + public function setEnabled(bool $enabled): void + { + $this->enabled = $enabled; + } + + public function getEditedAt(): ?DateTimeInterface + { + return $this->editedAt; + } + + public function setEditedAt(?DateTimeInterface $editedAt): void + { + $this->editedAt = $editedAt; + } + + public function getProductListings(): Collection + { + return $this->productListings; + } + + public function setProductListings(Collection $productListings): void + { + $this->productListings = $productListings; + } + + public function addProductListing(Listing $productListings): void + { + $this->productListings->add($productListings); + } + + public function getSlug(): ?string + { + return $this->slug; + } + + public function setSlug(?string $slug): void + { + $this->slug = $slug; + } + + public function getDescription(): ?string + { + return $this->description; + } + + public function setDescription(?string $description): void + { + $this->description = $description; + } + + /** @return Collection */ + public function getProducts(): Collection + { + return $this->products; + } + + public function addProduct(ProductInterface $product): void + { + if (false === $this->products->contains($product)) { + $this->products->add($product); + $product->setVendor($this); + } + } + + public function removeProduct(ProductInterface $product): void + { + if (true === $this->products->contains($product)) { + $this->products->removeElement($product); + } + } + + public function getImage(): ?LogoImageInterface + { + return $this->image; + } + + public function setImage(?LogoImageInterface $image): void + { + $this->image = $image; + } + + public function removeImage(): void + { + $this->image = null; + } + + public function getBackgroundImage(): ?BackgroundImageInterface + { + return $this->backgroundImage; + } + + public function setBackgroundImage(?BackgroundImageInterface $backgroundImage): void + { + $this->backgroundImage = $backgroundImage; + } + + public function removeBackgroundImage(): void + { + $this->backgroundImage = null; + } + + public function isVerified(): bool + { + return self::STATUS_VERIFIED === $this->getStatus(); + } + + /** @return Collection */ + public function getShippingMethods(): Collection + { + return $this->shippingMethods; + } + + public function hasShippingMethod(VendorShippingMethodInterface $shippingMethod): bool + { + return $this->shippingMethods->contains($shippingMethod); + } + + public function addShippingMethod(VendorShippingMethodInterface $shippingMethod): void + { + if (!$this->hasShippingMethod($shippingMethod)) { + $this->shippingMethods->add($shippingMethod); + } + } + + public function removeShippingMethod(VendorShippingMethodInterface $shippingMethod): void + { + if ($this->hasShippingMethod($shippingMethod)) { + $this->shippingMethods->removeElement($shippingMethod); + } + } + + public function getAverageRatingData(): array + { + $ratingSum = 0.0; + $productsRated = 0; + $reviewsCount = 0; + /** @var ProductInterface $product */ + foreach ($this->products as $product) { + if (0 < count($product->getAcceptedReviews())) { + $ratingSum += $product->getAverageRating(); + $productsRated += 1; + $reviewsCount += count($product->getAcceptedReviews()); + } + } + + if (0 === $productsRated) { + return [ + 'averageRating' => 0.0, + 'reviewsCount' => 0, + ]; + } + + return [ + 'averageRating' => $ratingSum / $productsRated, + 'reviewsCount' => $reviewsCount, + ]; + } + + public function getCommission(): ?int + { + return $this->commission; + } + + public function setCommission(?int $commission): void + { + $this->commission = $commission; + } + + public function getCommissionType(): string + { + return $this->commissionType; + } + + public function setCommissionType(string $commissionType): void + { + $this->commissionType = $commissionType; + } + + public function getSettlements(): Collection + { + return $this->settlements; + } + + public function setSettlements(Collection $settlements): void + { + $this->settlements = $settlements; + } + + public function getSettlementFrequency(): string + { + return $this->settlementFrequency; + } + + public function setSettlementFrequency(string $settlementFrequency): void + { + $this->settlementFrequency = $settlementFrequency; + } + + public function __toString(): string + { + /** @phpstan-ignore-next-line */ + return $this->getCompanyName(); + } + + public function getValidSettlementFrequency(): array + { + return VendorSettlementFrequency::SETTLEMENT_FREQUENCIES; + } + + public function getCreatedAt(): DateTimeInterface + { + return $this->createdAt; + } + + public function setCreatedAt(DateTimeInterface $createdAt): void + { + $this->createdAt = $createdAt; + } + + public function hasCyclicalSettlementFrequency(): bool + { + return in_array( + $this->getSettlementFrequency(), + VendorSettlementFrequency::CYCLICAL_SETTLEMENT_FREQUENCIES, + true + ); + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Entity/VendorInterface.php b/OpenMarketplace/src/Component/Vendor/Entity/VendorInterface.php new file mode 100644 index 0000000..7cdb35e --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Entity/VendorInterface.php @@ -0,0 +1,142 @@ + */ + public function getProducts(): Collection; + + public function addProduct(ProductInterface $product): void; + + public function removeProduct(ProductInterface $product): void; + + public function setImage(?LogoImageInterface $image): void; + + public function removeImage(): void; + + public function getBackgroundImage(): ?BackgroundImageInterface; + + public function setBackgroundImage(?BackgroundImageInterface $backgroundImage): void; + + public function removeBackgroundImage(): void; + + /** @return Collection */ + public function getProductListings(): Collection; + + /** + * @param Collection $productListings + */ + public function setProductListings(Collection $productListings): void; + + public function isVerified(): bool; + + /** @return Collection */ + public function getShippingMethods(): Collection; + + public function hasShippingMethod(VendorShippingMethodInterface $shippingMethod): bool; + + public function addShippingMethod(VendorShippingMethodInterface $shippingMethod): void; + + public function removeShippingMethod(VendorShippingMethodInterface $shippingMethod): void; + + public function getCommission(): ?int; + + public function setCommission(?int $commission): void; + + public function getCommissionType(): string; + + public function setCommissionType(string $commissionType): void; + + public function getSettlementFrequency(): string; + + public function setSettlementFrequency(string $settlementFrequency): void; + + public function getValidSettlementFrequency(): array; + + public function getSettlements(): Collection; + + public function setSettlements(Collection $settlements): void; + + public function getCreatedAt(): DateTimeInterface; + + public function setCreatedAt(DateTimeInterface $createdAt): void; + + public function hasCyclicalSettlementFrequency(): bool; +} diff --git a/OpenMarketplace/src/Component/Vendor/Entity/VendorShippingMethod.php b/OpenMarketplace/src/Component/Vendor/Entity/VendorShippingMethod.php new file mode 100644 index 0000000..0872772 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Entity/VendorShippingMethod.php @@ -0,0 +1,60 @@ +id; + } + + public function getVendor(): ?VendorInterface + { + return $this->vendor; + } + + public function setVendor(?VendorInterface $vendor): void + { + $this->vendor = $vendor; + } + + public function getShippingMethod(): ?ShippingMethodInterface + { + return $this->shippingMethod; + } + + public function setShippingMethod(?ShippingMethodInterface $shippingMethod): void + { + $this->shippingMethod = $shippingMethod; + } + + public function getChannelCode(): ?string + { + return $this->channelCode; + } + + public function setChannelCode(?string $channelCode): void + { + $this->channelCode = $channelCode; + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Entity/VendorShippingMethodInterface.php b/OpenMarketplace/src/Component/Vendor/Entity/VendorShippingMethodInterface.php new file mode 100644 index 0000000..d9f5972 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Entity/VendorShippingMethodInterface.php @@ -0,0 +1,30 @@ +defaultCommission = (int) $defaultCommission; + $this->defaultCommissionType = $defaultCommissionType; + } + + /** @return VendorInterface */ + public function createNew() + { + $vendor = new Vendor(); + $vendor->setCommission($this->defaultCommission); + $vendor->setCommissionType($this->defaultCommissionType); + + return $vendor; + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Factory/VendorShippingMethodFactory.php b/OpenMarketplace/src/Component/Vendor/Factory/VendorShippingMethodFactory.php new file mode 100755 index 0000000..ea2790e --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Factory/VendorShippingMethodFactory.php @@ -0,0 +1,39 @@ +createNew(); + + $vendorShippingMethod->setChannelCode($channelCode); + $vendorShippingMethod->setShippingMethod($shippingMethod); + $vendorShippingMethod->setVendor($vendor); + + return $vendorShippingMethod; + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Factory/VendorShippingMethodFactoryInterface.php b/OpenMarketplace/src/Component/Vendor/Factory/VendorShippingMethodFactoryInterface.php new file mode 100644 index 0000000..46134de --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Factory/VendorShippingMethodFactoryInterface.php @@ -0,0 +1,27 @@ +vendorRepository = $vendorRepository; + } + + public function generateSlug(string $companyName): string + { + if (null == $baseSlug = preg_replace('/\s+/', '-', $companyName)) { + throw new \Exception('Cannot generate slug from given company name.'); + } + + $slug = $baseSlug; + $number = 1; + while ($this->slugExists($slug)) { + $slug = $baseSlug . '-' . $number; + ++$number; + } + + return $slug; + } + + private function slugExists(string $slug): bool + { + $slug = $this->vendorRepository->findOneBy(['slug' => $slug]); + + return !(null === $slug); + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Generator/SlugGeneratorInterface.php b/OpenMarketplace/src/Component/Vendor/Generator/SlugGeneratorInterface.php new file mode 100644 index 0000000..80f0514 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Generator/SlugGeneratorInterface.php @@ -0,0 +1,17 @@ +getBackgroundImage(); + + if (!$backgroundImageUpdate) { + return; + } + + /** @var BackgroundImageInterface $backgroundImageEntity */ + $backgroundImageEntity = $vendor->getBackgroundImage(); + if (!$vendor->getBackgroundImage()) { + $backgroundImageEntity = $this->vendorBackgroundImageFactory->createNew(); + } + + $backgroundImageEntity->setPath($backgroundImageUpdate->getPath()); + $backgroundImageEntity->setOwner($vendor); + $vendor->setBackgroundImage($backgroundImageEntity); + + $backgroundImageUpdate->setPath(null); + + $this->entityManager->persist($backgroundImageUpdate); + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Profile/BackgroundImageOperatorInterface.php b/OpenMarketplace/src/Component/Vendor/Profile/BackgroundImageOperatorInterface.php new file mode 100644 index 0000000..6d371e0 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Profile/BackgroundImageOperatorInterface.php @@ -0,0 +1,20 @@ +setCountry($country); + $address->setPostalCode($postalCode); + $address->setStreet($street); + $address->setCity($city); + + return $address; + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Profile/Factory/AddressFactoryInterface.php b/OpenMarketplace/src/Component/Vendor/Profile/Factory/AddressFactoryInterface.php new file mode 100644 index 0000000..90a3e3f --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Profile/Factory/AddressFactoryInterface.php @@ -0,0 +1,25 @@ +setPath($path); + $vendorBackgroundImage->setOwner($vendor); + + return $vendorBackgroundImage; + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Profile/Factory/BackgroundImageFactoryInterface.php b/OpenMarketplace/src/Component/Vendor/Profile/Factory/BackgroundImageFactoryInterface.php new file mode 100644 index 0000000..9bc8b90 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Profile/Factory/BackgroundImageFactoryInterface.php @@ -0,0 +1,25 @@ +setPath($path); + $vendorImage->setOwner($vendor); + + return $vendorImage; + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Profile/Factory/LogoImageFactoryInterface.php b/OpenMarketplace/src/Component/Vendor/Profile/Factory/LogoImageFactoryInterface.php new file mode 100644 index 0000000..03b473b --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Profile/Factory/LogoImageFactoryInterface.php @@ -0,0 +1,25 @@ +vendorFactory = $vendorFactory; + } + + public function createVendor( + string $companyName, + string $taxIdentifier, + string $bankAccountNumber, + string $phoneNumber, + string $description, + AddressInterface $address + ): ProfileInterface { + $vendor = $this->createNew(); + $vendor->setPhoneNumber($phoneNumber); + $vendor->setCompanyName($companyName); + $vendor->setTaxIdentifier($taxIdentifier); + $vendor->setBankAccountNumber($bankAccountNumber); + $vendor->setDescription($description); + $vendor->setVendorAddress($address); + + return $vendor; + } + + public function createNew(): ProfileInterface + { + /** @var ProfileInterface $vendor */ + $vendor = $this->vendorFactory->createNew(); + + return $vendor; + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Profile/Factory/ProfileFactoryInterface.php b/OpenMarketplace/src/Component/Vendor/Profile/Factory/ProfileFactoryInterface.php new file mode 100644 index 0000000..94ca4d1 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Profile/Factory/ProfileFactoryInterface.php @@ -0,0 +1,29 @@ +createNew(); + $backgroundImage->setFile($uploadedBackgroundImage->getFile()); + $backgroundImage->setOwner($vendorProfile); + + return $backgroundImage; + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Profile/Factory/ProfileUpdateBackgroundImageFactoryInterface.php b/OpenMarketplace/src/Component/Vendor/Profile/Factory/ProfileUpdateBackgroundImageFactoryInterface.php new file mode 100644 index 0000000..032e66b --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Profile/Factory/ProfileUpdateBackgroundImageFactoryInterface.php @@ -0,0 +1,22 @@ +tokenGenerator = $tokenGenerator; + } + + public function createWithGeneratedTokenAndVendor( + VendorInterface $vendor + ): ProfileUpdateInterface { + $vendorUpdate = new ProfileUpdate(); + $vendorUpdate->setVendorAddress(new Address()); + $vendorUpdate->setToken($this->tokenGenerator->generate()); + $vendorUpdate->setVendor($vendor); + + return $vendorUpdate; + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Profile/Factory/ProfileUpdateFactoryInterface.php b/OpenMarketplace/src/Component/Vendor/Profile/Factory/ProfileUpdateFactoryInterface.php new file mode 100644 index 0000000..22cd18e --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Profile/Factory/ProfileUpdateFactoryInterface.php @@ -0,0 +1,20 @@ +createNew(); + $image->setFile($uploadedImage->getFile()); + $image->setOwner($vendorProfile); + + return $image; + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Profile/Factory/ProfileUpdateLogoImageFactoryInterface.php b/OpenMarketplace/src/Component/Vendor/Profile/Factory/ProfileUpdateLogoImageFactoryInterface.php new file mode 100644 index 0000000..038d9da --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Profile/Factory/ProfileUpdateLogoImageFactoryInterface.php @@ -0,0 +1,22 @@ +getImage(); + + if ($imageUpdate) { + /** @var LogoImageInterface $imageEntity */ + $imageEntity = $vendor->getImage(); + if (!$vendor->getImage()) { + $imageEntity = $this->vendorImageFactory->createNew(); + } + + $imageEntity->setPath($imageUpdate->getPath()); + $imageEntity->setOwner($vendor); + $vendor->setImage($imageEntity); + + $imageUpdate->setPath(null); + + $this->entityManager->persist($imageUpdate); + } + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Profile/LogoImageOperatorInterface.php b/OpenMarketplace/src/Component/Vendor/Profile/LogoImageOperatorInterface.php new file mode 100644 index 0000000..63c9ace --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Profile/LogoImageOperatorInterface.php @@ -0,0 +1,20 @@ +getVendorAddress(); + + if (null !== $pendingAddressChange) { + $this->entityManager->remove($pendingAddressChange); + } + + $this->entityManager->remove($profileUpdate); + $this->entityManager->flush(); + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Profile/ProfileUpdateRemoverInterface.php b/OpenMarketplace/src/Component/Vendor/Profile/ProfileUpdateRemoverInterface.php new file mode 100644 index 0000000..ccfad7d --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Profile/ProfileUpdateRemoverInterface.php @@ -0,0 +1,19 @@ +profileUpdateFactory->createWithGeneratedTokenAndVendor($currentVendor); + + if ($image && $image->getFile()) { + $imageEntity = $this->imageFactory->createWithFileAndOwner($image, $pendingVendorUpdate); + + $this->imageUploader->upload($imageEntity); + $pendingVendorUpdate->setImage($imageEntity); + $this->entityManager->persist($imageEntity); + } + + if ($image && !$image->getPath()) { + $currentVendor->setImage(null); + } + + if ($backgroundImage && $backgroundImage->getFile()) { + $backgroundImageEntity = $this->backgroundImageFactory->createWithFileAndOwner($backgroundImage, $pendingVendorUpdate); + + $this->imageUploader->upload($backgroundImageEntity); + $pendingVendorUpdate->setBackgroundImage($backgroundImageEntity); + $this->entityManager->persist($backgroundImageEntity); + } + + if ($backgroundImage && !$backgroundImage->getPath()) { + $currentVendor->setBackgroundImage(null); + } + + $this->entityManager->persist($pendingVendorUpdate); + + $token = $pendingVendorUpdate->getToken(); + + $this->setVendorFromData($pendingVendorUpdate, $vendorData); + + $this->entityManager->flush(); + $shopUser = $currentVendor->getShopUser(); + $email = $shopUser->getEmail(); + + $this->sender->send('vendor_profile_update', [$email], ['token' => $token]); + } + + public function setVendorFromData( + ProfileInterface $vendor, + ProfileInterface $data + ): void { + $vendor->setCompanyName($data->getCompanyName()); + $vendor->setTaxIdentifier($data->getTaxIdentifier()); + $vendor->setBankAccountNumber($data->getBankAccountNumber()); + $vendor->setPhoneNumber($data->getPhoneNumber()); + $vendor->setDescription($data->getDescription()); + + $newVendorAddress = $data->getVendorAddress(); + + if (null === $newVendorAddress) { + return; + } + + if (null !== $vendor->getVendorAddress()) { + $vendor->getVendorAddress()->setCity($newVendorAddress->getCity()); + $vendor->getVendorAddress()->setCountry($newVendorAddress->getCountry()); + $vendor->getVendorAddress()->setPostalCode($newVendorAddress->getPostalCode()); + $vendor->getVendorAddress()->setStreet($newVendorAddress->getStreet()); + } + + $this->entityManager->persist($vendor); + $this->entityManager->flush(); + } + + public function updateVendorFromPendingData(ProfileUpdateInterface $vendorData): void + { + $vendor = $vendorData->getVendor(); + + $this->setVendorFromData($vendor, $vendorData); + + if (null !== $vendorData->getBackgroundImage()) { + $this->vendorBackgroundImageOperator->replaceVendorImage($vendorData, $vendor); + } + if (null !== $vendorData->getImage()) { + $this->vendorLogoOperator->replaceVendorImage($vendorData, $vendor); + } + + $this->remover->removePendingUpdate($vendorData); + } +} diff --git a/OpenMarketplace/src/Component/Vendor/ProfileUpdaterInterface.php b/OpenMarketplace/src/Component/Vendor/ProfileUpdaterInterface.php new file mode 100644 index 0000000..c8bea15 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/ProfileUpdaterInterface.php @@ -0,0 +1,32 @@ +getId(); + + return $this->createQueryBuilder('c') + ->innerJoin('c.orders', 'o', ) + ->andWhere('o.vendor = :vendor') + ->setParameter('vendor', $vendorId) + ; + } + + public function findCustomerForVendor(VendorInterface $vendor, string $id): ?CustomerInterface + { + $vendorId = $vendor->getId(); + + return $this->createQueryBuilder('c') + ->innerJoin('c.orders', 'o') + ->andWhere('o.vendor = :vendor') + ->andWhere('c.id = :id') + ->setParameter('vendor', $vendorId) + ->setParameter('id', $id) + ->setMaxResults(1) + ->getQuery() + ->getOneOrNullResult(); + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Repository/CustomerRepositoryInterface.php b/OpenMarketplace/src/Component/Vendor/Repository/CustomerRepositoryInterface.php new file mode 100644 index 0000000..ff0645c --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Repository/CustomerRepositoryInterface.php @@ -0,0 +1,23 @@ +createListQueryBuilder() + ->andWhere('o.parent IS NULL') + ->getQuery() + ->getOneOrNullResult() + ; + + return $qb; + } + + return $this->findOneBySlug($slug, $locale); + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Repository/TaxonRepositoryInterface.php b/OpenMarketplace/src/Component/Vendor/Repository/TaxonRepositoryInterface.php new file mode 100644 index 0000000..f0f0249 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Repository/TaxonRepositoryInterface.php @@ -0,0 +1,19 @@ +createQueryBuilder('v') + ->andWhere('v.slug = :slug') + ->setParameter('slug', $slug) + ->getQuery() + ->getOneOrNullResult() + ; + } + + public function findAllBySettlementFrequency(string $frequency): iterable + { + return $this->createQueryBuilder('v') + ->andWhere('v.settlementFrequency = :frequency') + ->setParameter('frequency', $frequency) + ->getQuery() + ->getResult() + ; + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Repository/VendorRepositoryInterface.php b/OpenMarketplace/src/Component/Vendor/Repository/VendorRepositoryInterface.php new file mode 100644 index 0000000..f186ddf --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Repository/VendorRepositoryInterface.php @@ -0,0 +1,23 @@ +createQueryBuilder('o') + ->andWhere('o.vendor = :vendor') + ->andWhere('o.channelCode = :channelCode') + ->setParameter('vendor', $vendor) + ->setParameter('channelCode', $channel->getCode()) + ->getQuery() + ->getResult() + ; + } +} diff --git a/OpenMarketplace/src/Component/Vendor/Repository/VendorShippingMethodRepositoryInterface.php b/OpenMarketplace/src/Component/Vendor/Repository/VendorShippingMethodRepositoryInterface.php new file mode 100644 index 0000000..998d133 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Repository/VendorShippingMethodRepositoryInterface.php @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/doctrine/BackgroundImage.orm.xml b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/BackgroundImage.orm.xml new file mode 100644 index 0000000..cbcc1a6 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/BackgroundImage.orm.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/doctrine/LogoImage.orm.xml b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/LogoImage.orm.xml new file mode 100644 index 0000000..308b102 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/LogoImage.orm.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/doctrine/ProfileUpdate.Address.orm.xml b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/ProfileUpdate.Address.orm.xml new file mode 100644 index 0000000..51a9dae --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/ProfileUpdate.Address.orm.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/doctrine/ProfileUpdate.BackgroundImage.orm.xml b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/ProfileUpdate.BackgroundImage.orm.xml new file mode 100644 index 0000000..9eb6ca6 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/ProfileUpdate.BackgroundImage.orm.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/doctrine/ProfileUpdate.LogoImage.orm.xml b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/ProfileUpdate.LogoImage.orm.xml new file mode 100644 index 0000000..584ba72 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/ProfileUpdate.LogoImage.orm.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/doctrine/ProfileUpdate.ProfileUpdate.orm.xml b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/ProfileUpdate.ProfileUpdate.orm.xml new file mode 100644 index 0000000..bc30740 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/ProfileUpdate.ProfileUpdate.orm.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/doctrine/ShopUser.orm.xml b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/ShopUser.orm.xml new file mode 100644 index 0000000..7d5f9b7 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/ShopUser.orm.xml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/doctrine/Vendor.orm.xml b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/Vendor.orm.xml new file mode 100644 index 0000000..dd0b8f9 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/Vendor.orm.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/doctrine/VendorShippingMethod.orm.xml b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/VendorShippingMethod.orm.xml new file mode 100644 index 0000000..f5dfb4f --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/doctrine/VendorShippingMethod.orm.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/services.xml b/OpenMarketplace/src/Component/Vendor/Resources/services.xml new file mode 100644 index 0000000..788d597 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/services.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/services/factories.xml b/OpenMarketplace/src/Component/Vendor/Resources/services/factories.xml new file mode 100644 index 0000000..15b2cc5 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/services/factories.xml @@ -0,0 +1,16 @@ + + + + + + %env(DEFAULT_VENDOR_COMMISSION)% + %env(string:DEFAULT_VENDOR_COMMISSION_TYPE)% + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/services/generators.xml b/OpenMarketplace/src/Component/Vendor/Resources/services/generators.xml new file mode 100644 index 0000000..f45d506 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/services/generators.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/services/profile.xml b/OpenMarketplace/src/Component/Vendor/Resources/services/profile.xml new file mode 100644 index 0000000..41f1de1 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/services/profile.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/services/repositories.xml b/OpenMarketplace/src/Component/Vendor/Resources/services/repositories.xml new file mode 100644 index 0000000..d839cf1 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/services/repositories.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/validation/Address.xml b/OpenMarketplace/src/Component/Vendor/Resources/validation/Address.xml new file mode 100644 index 0000000..1dae756 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/validation/Address.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/validation/BackgroundImage.xml b/OpenMarketplace/src/Component/Vendor/Resources/validation/BackgroundImage.xml new file mode 100644 index 0000000..a502af5 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/validation/BackgroundImage.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/validation/Conversation.xml b/OpenMarketplace/src/Component/Vendor/Resources/validation/Conversation.xml new file mode 100644 index 0000000..ac2e18a --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/validation/Conversation.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/validation/LogoImage.xml b/OpenMarketplace/src/Component/Vendor/Resources/validation/LogoImage.xml new file mode 100644 index 0000000..86a240b --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/validation/LogoImage.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/validation/ProductVariant.xml b/OpenMarketplace/src/Component/Vendor/Resources/validation/ProductVariant.xml new file mode 100644 index 0000000..a405026 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/validation/ProductVariant.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/Resources/validation/Vendor.xml b/OpenMarketplace/src/Component/Vendor/Resources/validation/Vendor.xml new file mode 100644 index 0000000..f2bde3b --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/Resources/validation/Vendor.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/src/Component/Vendor/TaxonContext.php b/OpenMarketplace/src/Component/Vendor/TaxonContext.php new file mode 100644 index 0000000..f16f00e --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/TaxonContext.php @@ -0,0 +1,30 @@ +taxonRepository = $taxonRepository; + } + + public function getForVendorPage(?string $slug, string $locale): ?TaxonInterface + { + return $this->taxonRepository->findForVendorPage($slug, $locale); + } +} diff --git a/OpenMarketplace/src/Component/Vendor/TaxonContextInterface.php b/OpenMarketplace/src/Component/Vendor/TaxonContextInterface.php new file mode 100644 index 0000000..2526a0a --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/TaxonContextInterface.php @@ -0,0 +1,19 @@ +security = $security; + } + + public function getVendor(): VendorInterface + { + /** @var ShopUserInterface|UserInterface|null $user */ + $user = $this->security->getUser(); + if (false === $user instanceof ShopUserInterface) { + throw new ShopUserNotFoundException(); + } + + /** @var VendorInterface|null $vendor */ + $vendor = $user->getVendor(); + + if (null === $vendor) { + throw new ShopUserHasNoVendorContextException(); + } + + return $vendor; + } +} diff --git a/OpenMarketplace/src/Component/Vendor/VendorContextInterface.php b/OpenMarketplace/src/Component/Vendor/VendorContextInterface.php new file mode 100644 index 0000000..6023c34 --- /dev/null +++ b/OpenMarketplace/src/Component/Vendor/VendorContextInterface.php @@ -0,0 +1,19 @@ +getProjectDir() . '/var/cache/' . $this->environment; + } + + public function getLogDir(): string + { + return $this->getProjectDir() . '/var/log'; + } + + public function registerBundles(): iterable + { + foreach ($this->getConfigurationDirectories() as $confDir) { + $bundlesFile = $confDir . '/bundles.php'; + if (false === is_file($bundlesFile)) { + continue; + } + yield from $this->registerBundlesFromFile($bundlesFile); + } + } + + private function isTestEnvironment(): bool + { + return 0 === strpos($this->getEnvironment(), 'test'); + } + + protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void + { + foreach ($this->getConfigurationDirectories() as $confDir) { + $bundlesFile = $confDir . '/bundles.php'; + if (false === is_file($bundlesFile)) { + continue; + } + $container->addResource(new FileResource($bundlesFile)); + } + + $container->setParameter('container.dumper.inline_class_loader', true); + + foreach ($this->getConfigurationDirectories() as $confDir) { + $this->loadContainerConfiguration($loader, $confDir); + } + } + + protected function configureRoutes(RouteCollectionBuilder $routes): void + { + foreach ($this->getConfigurationDirectories() as $confDir) { + $this->loadRoutesConfiguration($routes, $confDir); + } + } + + protected function getContainerBaseClass(): string + { + if ($this->isTestEnvironment() && class_exists(MockerContainer::class)) { + return MockerContainer::class; + } + + return parent::getContainerBaseClass(); + } + + /** + * @return BundleInterface[] + */ + private function registerBundlesFromFile(string $bundlesFile): iterable + { + $contents = require $bundlesFile; + foreach ($contents as $class => $envs) { + if (isset($envs['all']) || isset($envs[$this->environment])) { + /** @phpstan-ignore-next-line */ + yield new $class(); + } + } + } + + /** + * @return string[] + */ + private function getConfigurationDirectories(): iterable + { + yield $this->getProjectDir() . '/config'; + $syliusConfigDir = $this->getProjectDir() . '/config/sylius/' . SyliusKernel::MAJOR_VERSION . '.' . SyliusKernel::MINOR_VERSION; + if (is_dir($syliusConfigDir)) { + yield $syliusConfigDir; + } + $symfonyConfigDir = $this->getProjectDir() . '/config/symfony/' . BaseKernel::MAJOR_VERSION . '.' . BaseKernel::MINOR_VERSION; + if (is_dir($symfonyConfigDir)) { + yield $symfonyConfigDir; + } + } + + private function loadContainerConfiguration(LoaderInterface $loader, string $confDir): void + { + $loader->load($confDir . '/{config}' . self::CONFIG_EXTS, 'glob'); + $loader->load($confDir . '/{packages}/*' . self::CONFIG_EXTS, 'glob'); + $loader->load($confDir . '/{packages}/' . $this->environment . '/**/*' . self::CONFIG_EXTS, 'glob'); + $loader->load($confDir . '/{services}' . self::CONFIG_EXTS, 'glob'); + $loader->load($confDir . '/{services}_' . $this->environment . self::CONFIG_EXTS, 'glob'); + } + + private function loadRoutesConfiguration(RouteCollectionBuilder $routes, string $confDir): void + { + $routes->import($confDir . '/{routes}/*' . self::CONFIG_EXTS, '/', 'glob'); + $routes->import($confDir . '/{routes}/' . $this->environment . '/**/*' . self::CONFIG_EXTS, '/', 'glob'); + $routes->import($confDir . '/{routes}' . self::CONFIG_EXTS, '/', 'glob'); + $routes->import($confDir . '/{routing}' . self::CONFIG_EXTS, '/', 'glob'); + } +} diff --git a/OpenMarketplace/symfony.lock b/OpenMarketplace/symfony.lock new file mode 100644 index 0000000..24f7e06 --- /dev/null +++ b/OpenMarketplace/symfony.lock @@ -0,0 +1,491 @@ +{ + "api-platform/core": { + "version": "2.7", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "2.5", + "ref": "05b57782a78c21a664a42055dc11cf1954ca36bb" + }, + "files": [ + "config/packages/api_platform.yaml", + "config/routes/api_platform.yaml", + "src/Entity/.gitignore" + ] + }, + "babdev/pagerfanta-bundle": { + "version": "v3.7.0" + }, + "bitbag/cms-plugin": { + "version": "3.3", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "3.0", + "ref": "e3c6714d3910e4a76171a069242fe2a2ceb220af" + } + }, + "bitbag/wishlist-plugin": { + "version": "v3.0.3" + }, + "doctrine/annotations": { + "version": "1.14", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "1.0", + "ref": "a2759dd6123694c8d901d0ec80006e044c2e6457" + }, + "files": [ + "config/routes/annotations.yaml" + ] + }, + "doctrine/doctrine-bundle": { + "version": "2.7", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "2.4", + "ref": "013b823e7fee65890b23e40f31e6667a1ac519ac" + }, + "files": [ + "config/packages/doctrine.yaml", + "src/Entity/.gitignore", + "src/Repository/.gitignore" + ] + }, + "doctrine/doctrine-migrations-bundle": { + "version": "3.1", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "3.1", + "ref": "1d01ec03c6ecbd67c3375c5478c9a423ae5d6a33" + }, + "files": [ + "config/packages/doctrine_migrations.yaml", + "migrations/.gitignore" + ] + }, + "friends-of-behat/symfony-extension": { + "version": "2.4", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "2.0", + "ref": "1e012e04f573524ca83795cd19df9ea690adb604" + } + }, + "friendsofphp/php-cs-fixer": { + "version": "3.14", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "3.0", + "ref": "be2103eb4a20942e28a6dd87736669b757132435" + }, + "files": [ + ".php-cs-fixer.dist.php" + ] + }, + "friendsofsymfony/ckeditor-bundle": { + "version": "2.4", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "2.0", + "ref": "f5ad42002183a6881962683e6d84bbb25cdfce5d" + } + }, + "friendsofsymfony/oauth-server-bundle": { + "version": "2.0", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "1.6", + "ref": "7300db1277b1ba025cdc2791171d9bf3e7adcc42" + } + }, + "friendsofsymfony/rest-bundle": { + "version": "3.5", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "2.2", + "ref": "fa845143b7e0a4c70aedd1a88c549e6d977e9ae5" + } + }, + "jms/serializer-bundle": { + "version": "4.2", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "4.0", + "ref": "cc04e10cf7171525b50c18b36004edf64cb478be" + } + }, + "knplabs/knp-gaufrette-bundle": { + "version": "v0.8.0" + }, + "knplabs/knp-menu-bundle": { + "version": "v3.2.0" + }, + "lexik/jwt-authentication-bundle": { + "version": "2.18", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "2.5", + "ref": "5b2157bcd5778166a5696e42f552ad36529a07a6" + }, + "files": [ + "config/packages/lexik_jwt_authentication.yaml" + ] + }, + "liip/imagine-bundle": { + "version": "2.10", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "1.8", + "ref": "d1227d002b70d1a1f941d91845fcd7ac7fbfc929" + } + }, + "nelmio/alice": { + "version": "3.10", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "3.3", + "ref": "42b52d2065dc3fde27912d502c18ca1926e35ae2" + }, + "files": [ + "config/packages/nelmio_alice.yaml" + ] + }, + "payum/payum-bundle": { + "version": "2.5", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "2.4", + "ref": "518ac22defa04a8a1d82479ed362e2921487adf0" + } + }, + "phpunit/phpunit": { + "version": "9.6", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "9.3", + "ref": "a6249a6c4392e9169b87abf93225f7f9f59025e6" + }, + "files": [ + ".env.test", + "phpunit.xml.dist", + "tests/bootstrap.php" + ] + }, + "ramsey/uuid-doctrine": { + "version": "1.8", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "1.3", + "ref": "471aed0fbf5620b8d7f92b7a5ebbbf6c0945c27a" + } + }, + "sensiolabs/security-checker": { + "version": "6.0", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "4.0", + "ref": "160c9b600564faa1224e8f387d49ef13ceb8b793" + }, + "files": [ + "config/packages/security_checker.yaml" + ] + }, + "sonata-project/block-bundle": { + "version": "4.19", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "4.11", + "ref": "b4edd2a1e6ac1827202f336cac2771cb529de542" + } + }, + "sonata-project/doctrine-extensions": { + "version": "1.18", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "1.8", + "ref": "4ea4a4b6730f83239608d7d4c849533645c70169" + } + }, + "sonata-project/form-extensions": { + "version": "1.18", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "1.4", + "ref": "9c8a1e8ce2b1f215015ed16652c4ed18eb5867fd" + } + }, + "squizlabs/php_codesniffer": { + "version": "3.7", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "3.6", + "ref": "1019e5c08d4821cb9b77f4891f8e9c31ff20ac6f" + } + }, + "stof/doctrine-extensions-bundle": { + "version": "1.7", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "1.2", + "ref": "e805aba9eff5372e2d149a9ff56566769e22819d" + } + }, + "sylius-labs/doctrine-migrations-extra-bundle": { + "version": "v0.1.4" + }, + "sylius/calendar": { + "version": "v0.3.0" + }, + "sylius/fixtures-bundle": { + "version": "v1.8.0" + }, + "sylius/grid-bundle": { + "version": "v1.12.0" + }, + "sylius/mailer-bundle": { + "version": "v1.8.1" + }, + "sylius/resource-bundle": { + "version": "1.10", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "1.6", + "ref": "bfd4306c8e26b4aed0790ebde89a2c949e1398a2" + } + }, + "sylius/theme-bundle": { + "version": "v2.3.0" + }, + "symfony/console": { + "version": "5.4", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "5.3", + "ref": "da0c8be8157600ad34f10ff0c9cc91232522e047" + }, + "files": [ + "bin/console" + ] + }, + "symfony/debug-bundle": { + "version": "5.4", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "5.3", + "ref": "5aa8aa48234c8eb6dbdd7b3cd5d791485d2cec4b" + }, + "files": [ + "config/packages/debug.yaml" + ] + }, + "symfony/flex": { + "version": "1.19", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "1.0", + "ref": "146251ae39e06a95be0fe3d13c807bcf3938b172" + }, + "files": [ + ".env" + ] + }, + "symfony/framework-bundle": { + "version": "5.4", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "5.4", + "ref": "3cd216a4d007b78d8554d44a5b1c0a446dab24fb" + }, + "files": [ + "config/packages/cache.yaml", + "config/packages/framework.yaml", + "config/preload.php", + "config/routes/framework.yaml", + "config/services.yaml", + "public/index.php", + "src/Controller/.gitignore", + "src/Kernel.php" + ] + }, + "symfony/messenger": { + "version": "5.4", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "5.4", + "ref": "8bd5f27013fb1d7217191c548e340f0bdb11912c" + }, + "files": [ + "config/packages/messenger.yaml" + ] + }, + "symfony/monolog-bundle": { + "version": "3.8", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "3.7", + "ref": "213676c4ec929f046dfde5ea8e97625b81bc0578" + }, + "files": [ + "config/packages/monolog.yaml" + ] + }, + "symfony/routing": { + "version": "5.4", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "5.3", + "ref": "85de1d8ae45b284c3c84b668171d2615049e698f" + }, + "files": [ + "config/packages/routing.yaml", + "config/routes.yaml" + ] + }, + "symfony/security-bundle": { + "version": "5.4", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "5.3", + "ref": "98f1f2b0d635908c2b40f3675da2d23b1a069d30" + }, + "files": [ + "config/packages/security.yaml" + ] + }, + "symfony/swiftmailer-bundle": { + "version": "3.5", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "2.5", + "ref": "f0b2fccdca2dfd97dc2fd5ad216d5e27c4f895ac" + }, + "files": [ + "config/packages/dev/swiftmailer.yaml", + "config/packages/swiftmailer.yaml", + "config/packages/test/swiftmailer.yaml" + ] + }, + "symfony/translation": { + "version": "5.4", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "5.3", + "ref": "da64f5a2b6d96f5dc24914517c0350a5f91dee43" + }, + "files": [ + "config/packages/translation.yaml", + "translations/.gitignore" + ] + }, + "symfony/twig-bundle": { + "version": "5.4", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "5.4", + "ref": "bb2178c57eee79e6be0b297aa96fc0c0def81387" + }, + "files": [ + "config/packages/twig.yaml", + "templates/base.html.twig" + ] + }, + "symfony/validator": { + "version": "5.4", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "5.3", + "ref": "c32cfd98f714894c4f128bb99aa2530c1227603c" + }, + "files": [ + "config/packages/validator.yaml" + ] + }, + "symfony/web-profiler-bundle": { + "version": "5.4", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "5.3", + "ref": "24bbc3d84ef2f427f82104f766014e799eefcc3e" + }, + "files": [ + "config/packages/web_profiler.yaml", + "config/routes/web_profiler.yaml" + ] + }, + "symfony/webpack-encore-bundle": { + "version": "1.16", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "1.10", + "ref": "f8fc53f1942f76679e9ee3c25fd44865355707b5" + }, + "files": [ + "assets/app.js", + "assets/bootstrap.js", + "assets/controllers.json", + "assets/controllers/hello_controller.js", + "assets/styles/app.css", + "config/packages/webpack_encore.yaml", + "package.json", + "webpack.config.js" + ] + }, + "theofidry/alice-data-fixtures": { + "version": "1.5", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "1.0", + "ref": "fe5a50faf580eb58f08ada2abe8afbd2d4941e05" + } + }, + "willdurand/hateoas-bundle": { + "version": "2.5", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "2.0", + "ref": "34df072c6edaa61ae19afb2f3a239f272fecab87" + } + }, + "winzou/state-machine-bundle": { + "version": "0.6.0" + } +} diff --git a/OpenMarketplace/templates/.gitignore b/OpenMarketplace/templates/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/OpenMarketplace/templates/Configuration/Event/Admin/Settlement/Show/details.html.twig b/OpenMarketplace/templates/Configuration/Event/Admin/Settlement/Show/details.html.twig new file mode 100644 index 0000000..7b3eed2 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Event/Admin/Settlement/Show/details.html.twig @@ -0,0 +1,8 @@ +
+

{{ 'sylius.ui.details'|trans }}

+
+
+ {{ sylius_template_event('open_marketplace.admin.settlement.show.details_content', _context) }} +
+
+
diff --git a/OpenMarketplace/templates/Configuration/Event/Admin/Settlement/Show/detailsTable.html.twig b/OpenMarketplace/templates/Configuration/Event/Admin/Settlement/Show/detailsTable.html.twig new file mode 100644 index 0000000..e19b34c --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Event/Admin/Settlement/Show/detailsTable.html.twig @@ -0,0 +1,52 @@ +{% import "@SyliusAdmin/Common/Macro/money.html.twig" as money %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ 'open_marketplace.ui.status'|trans }} + {% include 'Configuration/Grid/Admin/Field/settlementStatus.html.twig' with {data: settlement.status} %} +
{{ 'open_marketplace.ui.total_amount'|trans }} + {{ money.format(settlement.totalAmount, settlement.channel.baseCurrency.code) }}
{{ 'open_marketplace.ui.total_commission_amount'|trans }}{{ money.format(settlement.totalCommissionAmount, settlement.channel.baseCurrency.code) }}
{{ 'open_marketplace.ui.total_profit_amount'|trans }}{{ money.format(settlement.totalAmount - settlement.totalCommissionAmount, settlement.channel.baseCurrency.code) }}
{{ 'open_marketplace.ui.period'|trans }} + {{ settlement.startDate|format_datetime() }} - + {{ settlement.endDate|format_datetime() }} +
{{ 'open_marketplace.ui.created_at'|trans }} + {{ settlement.createdAt|format_datetime() }}
{{ 'open_marketplace.ui.updated_at'|trans }} + {{ settlement.updatedAt|format_datetime() }}
{{ 'open_marketplace.ui.channel'|trans }}{% include '@SyliusAdmin/Common/_channel.html.twig' with {'channel': settlement.channel} %}
{{ 'open_marketplace.ui.total_orders'|trans }}{{ count_orders_for_settlement(settlement) }}
diff --git a/OpenMarketplace/templates/Configuration/Event/Admin/Settlement/ShowOrders/details.html.twig b/OpenMarketplace/templates/Configuration/Event/Admin/Settlement/ShowOrders/details.html.twig new file mode 100644 index 0000000..defee44 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Event/Admin/Settlement/ShowOrders/details.html.twig @@ -0,0 +1 @@ +{{ sylius_template_event('open_marketplace.admin.settlement.show_orders.details_content', _context) }} diff --git a/OpenMarketplace/templates/Configuration/Event/Admin/Settlement/ShowOrders/grid.html.twig b/OpenMarketplace/templates/Configuration/Event/Admin/Settlement/ShowOrders/grid.html.twig new file mode 100644 index 0000000..f470d42 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Event/Admin/Settlement/ShowOrders/grid.html.twig @@ -0,0 +1 @@ +{{ sylius_grid_render(resources, '@SyliusAdmin/Grid/_default.html.twig') }} diff --git a/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Show/details.html.twig b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Show/details.html.twig new file mode 100644 index 0000000..f1c753f --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Show/details.html.twig @@ -0,0 +1,8 @@ +
+

{{ 'sylius.ui.details'|trans }}

+
+
+ {{ sylius_template_event('open_marketplace.admin.vendor.show.details_content', _context) }} +
+
+
diff --git a/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Show/detailsLabels.html.twig b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Show/detailsLabels.html.twig new file mode 100644 index 0000000..6fcb8ba --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Show/detailsLabels.html.twig @@ -0,0 +1,11 @@ +{% if vendor.status == constant('BitBag\\OpenMarketplace\\Component\\Vendor\\Entity\\VendorInterface::STATUS_VERIFIED') %} + {{ 'open_marketplace.ui.verified'|trans }} +{% else %} + {{ 'open_marketplace.ui.unverified'|trans }} +{% endif %} + +{% if vendor.enabled == true %} + {{ 'open_marketplace.ui.enabled'|trans }} +{% else %} + {{ 'open_marketplace.ui.disabled'|trans }} +{% endif %} diff --git a/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Show/detailsTable.html.twig b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Show/detailsTable.html.twig new file mode 100644 index 0000000..5c49274 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Show/detailsTable.html.twig @@ -0,0 +1,61 @@ + + + + + + + + + + + {% if vendor.image is not null %} + + + + + {% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ 'open_marketplace.ui.shop_user'|trans }} + {{ vendor.shopUser.username }} +
{{ 'open_marketplace.ui.company_name'|trans }}{{ vendor.companyName }}
{{ 'open_marketplace.ui.logo'|trans }} +
{{ 'open_marketplace.ui.tax_id'|trans }} {{ vendor.taxIdentifier }}
{{ 'open_marketplace.ui.bank_account_number'|trans }} {{ vendor.bankAccountNumber }}
{{ 'open_marketplace.ui.phone_number'|trans }}{{ vendor.phoneNumber }}
{{ 'open_marketplace.ui.country'|trans }}{{ vendor.vendorAddress.country }}
{{ 'open_marketplace.ui.city'|trans }}{{ vendor.vendorAddress.city }}
{{ 'open_marketplace.ui.street'|trans }}{{ vendor.vendorAddress.street }}
{{ 'open_marketplace.ui.postal_code'|trans }}{{ vendor.vendorAddress.postalCode }}
{{ 'open_marketplace.ui.commission'|trans }} (%){{ vendor.commission }}
{{ 'open_marketplace.ui.commission_type'|trans }}{{ vendor.commissionType }}
{{ 'open_marketplace.ui.settlement_frequency'|trans }}{{ ['open_marketplace.ui', vendor.settlementFrequency]|join('.')|trans }}
diff --git a/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/_commission.html.twig b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/_commission.html.twig new file mode 100644 index 0000000..2815554 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/_commission.html.twig @@ -0,0 +1,6 @@ +

{{ 'open_marketplace.ui.vendor_commission'|trans }}

+ +
+ {{ form_row(form.commission) }} + {{ form_row(form.commissionType) }} +
diff --git a/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/_details.html.twig b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/_details.html.twig new file mode 100644 index 0000000..756ec2d --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/_details.html.twig @@ -0,0 +1,12 @@ +{% if vendor.editedAt is not null %} + {{ 'Vendor requested changes on ' ~ vendor.editedAt|date("d.m.Y H:i:s") }} +{% endif %} +

{{ 'open_marketplace.ui.vendor_details'|trans }}

+ +
+ {{ form_row(form.companyName) }} + {{ form_row(form.taxIdentifier) }} +
+ +{{ form_row(form.bankAccountNumber) }} +{{ form_row(form.phoneNumber) }} diff --git a/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/_settlement.html.twig b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/_settlement.html.twig new file mode 100644 index 0000000..e486c65 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/_settlement.html.twig @@ -0,0 +1,5 @@ +

{{ 'open_marketplace.ui.settlement'|trans }}

+ +
+ {{ form_row(form.settlementFrequency) }} +
diff --git a/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/columns.html.twig b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/columns.html.twig new file mode 100644 index 0000000..01ae34d --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/columns.html.twig @@ -0,0 +1,7 @@ +
+ {{ sylius_template_event('open_marketplace.admin.vendor.form.first_column', _context) }} +
+ +
+ {{ sylius_template_event('open_marketplace.admin.vendor.form.second_column', _context) }} +
diff --git a/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/content.html.twig b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/content.html.twig new file mode 100644 index 0000000..03abdd3 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/content.html.twig @@ -0,0 +1,27 @@ +{% set index_url = path( + configuration.vars.index.route.name|default(configuration.getRouteName('index')), + configuration.vars.index.route.parameters|default(configuration.vars.route.parameters|default({})) +) +%} + +
+ {{ form_start(form, {'action': path(configuration.getRouteName('update'), configuration.vars.route.parameters|default({ 'id': resource.id })), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }} + + {% include '@SyliusAdmin/Crud/form_validation_errors_checker.html.twig' %} + + {% if not form._token.isRendered %} + {{ form_row(form._token) }} + + {{ form_errors(form) }} + +
+ {{ sylius_template_event('open_marketplace.admin.vendor.form.content', _context) }} +
+ {% endif %} + + {{ sylius_template_event([event_prefix ~ '.form', 'sylius.admin.update.form'], {'metadata': metadata, 'resource': resource, 'form': form}) }} + + {% include '@SyliusUi/Form/Buttons/_update.html.twig' with {'paths': {'cancel': index_url}} %} + + {{ form_end(form, {'render_rest': false}) }} +
diff --git a/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/firstColumn.html.twig b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/firstColumn.html.twig new file mode 100644 index 0000000..b1b72ce --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/firstColumn.html.twig @@ -0,0 +1,7 @@ +
+ {{ sylius_template_event('open_marketplace.admin.vendor.form.vendor_details', _context) }} +
+ +
+ {{ sylius_template_event('open_marketplace.admin.vendor.form.vendor_commission', _context) }} +
diff --git a/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/secondColumn.html.twig b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/secondColumn.html.twig new file mode 100644 index 0000000..5a9e598 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/secondColumn.html.twig @@ -0,0 +1,6 @@ +
+ {{ sylius_template_event('open_marketplace.admin.vendor.form.vendor_address', _context) }} +
+
+ {{ sylius_template_event('open_marketplace.admin.vendor.form.vendor_settlement', _context) }} +
diff --git a/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/vendorAddress.html.twig b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/vendorAddress.html.twig new file mode 100644 index 0000000..36c572c --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Event/Admin/Vendor/Update/vendorAddress.html.twig @@ -0,0 +1,6 @@ +

{{ 'open_marketplace.ui.vendor_address'|trans }}

+ +{{ form_row(form.vendorAddress.country) }} +{{ form_row(form.vendorAddress.city) }} +{{ form_row(form.vendorAddress.street) }} +{{ form_row(form.vendorAddress.postalCode) }} diff --git a/OpenMarketplace/templates/Configuration/Event/Shop/Account/Menu/content.html.twig b/OpenMarketplace/templates/Configuration/Event/Shop/Account/Menu/content.html.twig new file mode 100644 index 0000000..78bc830 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Event/Shop/Account/Menu/content.html.twig @@ -0,0 +1 @@ +{{ knp_menu_render('open_marketplace.core.vendor.menu', {'template': '@SyliusShop/Menu/simple.html.twig'}) }} diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Action/editVendor.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Action/editVendor.html.twig new file mode 100644 index 0000000..694f0c4 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Action/editVendor.html.twig @@ -0,0 +1,9 @@ +{% import '@SyliusUi/Macro/buttons.html.twig' as buttons %} + +{% set path = options.link.url|default(path(options.link.route|default(grid.requestConfiguration.getRouteName('update')), options.link.parameters|default({'id': data.id}))) %} + +{% if data.status == 'verified' %} + {{ buttons.default(path, 'open_marketplace.ui.edit', data.id, 'pencil', options.class is defined ? options.class : '') }} +{% endif %} + + diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Action/enableVendor.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Action/enableVendor.html.twig new file mode 100644 index 0000000..df28b6b --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Action/enableVendor.html.twig @@ -0,0 +1,13 @@ +{% set path_suffix = data.enabled ? 'disable' : 'enable' %} +{% set path = 'open_marketplace_admin_vendor_' ~ path_suffix %} +{% set label = 'open_marketplace.ui.' ~ path_suffix %} +{% set icon = data.enabled ? 'lock' : 'lock open'%} +{% set color = data.enabled ? 'yellow' : 'primary'%} + +
+ + + +
diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Action/productDetails.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Action/productDetails.html.twig new file mode 100644 index 0000000..a4b2dac --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Action/productDetails.html.twig @@ -0,0 +1,5 @@ +{% import '@SyliusUi/Macro/buttons.html.twig' as buttons %} + +{% set path = options.link.url|default(path(options.link.route|default(options.link.route), options.link.parameters|default({'id': data.id}))) %} + +{{ buttons.show(path, action.label) }} diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Action/restore.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Action/restore.html.twig new file mode 100644 index 0000000..1a4985a --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Action/restore.html.twig @@ -0,0 +1,9 @@ +{% set path = path('open_marketplace_admin_product_listing_restore', { 'id': data.id }) %} + +{% if data.removed == true %} +
+ +
+{% endif %} diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Action/showVendorProductListings.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Action/showVendorProductListings.html.twig new file mode 100644 index 0000000..9595478 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Action/showVendorProductListings.html.twig @@ -0,0 +1,4 @@ + + + {{ 'open_marketplace.ui.show_product_listings'|trans }} + diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Action/showVendorSettlements.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Action/showVendorSettlements.html.twig new file mode 100644 index 0000000..55d9e66 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Action/showVendorSettlements.html.twig @@ -0,0 +1,4 @@ + + + {{ 'open_marketplace.ui.show_settlements'|trans }} + diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Action/showVendorVirtualWallets.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Action/showVendorVirtualWallets.html.twig new file mode 100644 index 0000000..b9fa292 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Action/showVendorVirtualWallets.html.twig @@ -0,0 +1,4 @@ + + + {{ 'open_marketplace.ui.show_virtual_wallets'|trans }} + diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Field/enabled.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Field/enabled.html.twig new file mode 100644 index 0000000..3edf228 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Field/enabled.html.twig @@ -0,0 +1,2 @@ +{% import '@SyliusUi/Macro/labels.html.twig' as label %} +{{ label.status(data) }} diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Field/money.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Field/money.html.twig new file mode 100644 index 0000000..4b6a43e --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Field/money.html.twig @@ -0,0 +1 @@ +{{ attribute(data, options.vars.method)|sylius_format_money(data.channel.baseCurrency.code, sylius_base_locale) }} diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Field/productListingName.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Field/productListingName.html.twig new file mode 100644 index 0000000..6bd5211 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Field/productListingName.html.twig @@ -0,0 +1,7 @@ +{% if data %} + {{ data }} +{% else %} +

+ {{ 'sylius.ui.missing_translation'|trans }} +

+{% endif %} diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Field/productListingVendor.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Field/productListingVendor.html.twig new file mode 100644 index 0000000..849adb4 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Field/productListingVendor.html.twig @@ -0,0 +1,3 @@ + + {{ data.companyName ~ ' ' ~ data.shopUser.customer.fullName }} + diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Field/settlementPeriod.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Field/settlementPeriod.html.twig new file mode 100644 index 0000000..f3fa5b7 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Field/settlementPeriod.html.twig @@ -0,0 +1 @@ +{{ [data.startDate|format_date(pattern='dd/MM/YYYY'), data.endDate|format_date(pattern='dd/MM/YYYY')]|join(' - ') }} diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Field/settlementStatus.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Field/settlementStatus.html.twig new file mode 100644 index 0000000..26deaba --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Field/settlementStatus.html.twig @@ -0,0 +1,3 @@ +{% set value = 'open_marketplace.ui.settlement_status.' ~ data %} + +{% include '@SyliusUi/Label/_default.html.twig' with {'value': value} %} diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Field/settlementTotals.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Field/settlementTotals.html.twig new file mode 100644 index 0000000..4b6a43e --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Field/settlementTotals.html.twig @@ -0,0 +1 @@ +{{ attribute(data, options.vars.method)|sylius_format_money(data.channel.baseCurrency.code, sylius_base_locale) }} diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Field/status.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Field/status.html.twig new file mode 100644 index 0000000..787fe45 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Field/status.html.twig @@ -0,0 +1,8 @@ +{% set map = { + 'verified': {'color': 'teal', 'icon': 'check'}, + 'unverified': {'color': 'yellow', 'icon': 'clock'} +} %} + + + {{ data|capitalize }} + diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Filter/productListingStatus.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Filter/productListingStatus.html.twig new file mode 100644 index 0000000..0daf498 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Filter/productListingStatus.html.twig @@ -0,0 +1,3 @@ +{% form_theme form '@SyliusUi/Form/theme.html.twig' %} + +{{ form_row(form, {'label': filter.label}) }} diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Filter/settlementPeriod.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Filter/settlementPeriod.html.twig new file mode 100644 index 0000000..0daf498 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Filter/settlementPeriod.html.twig @@ -0,0 +1,3 @@ +{% form_theme form '@SyliusUi/Form/theme.html.twig' %} + +{{ form_row(form, {'label': filter.label}) }} diff --git a/OpenMarketplace/templates/Configuration/Grid/Admin/Filter/settlementStatus.html.twig b/OpenMarketplace/templates/Configuration/Grid/Admin/Filter/settlementStatus.html.twig new file mode 100644 index 0000000..0daf498 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Admin/Filter/settlementStatus.html.twig @@ -0,0 +1,3 @@ +{% form_theme form '@SyliusUi/Form/theme.html.twig' %} + +{{ form_row(form, {'label': filter.label}) }} diff --git a/OpenMarketplace/templates/Configuration/Grid/Common/Field/productListingStatus.html.twig b/OpenMarketplace/templates/Configuration/Grid/Common/Field/productListingStatus.html.twig new file mode 100644 index 0000000..1d09681 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Common/Field/productListingStatus.html.twig @@ -0,0 +1,10 @@ +{% set map = { + 'verified': {'color': 'teal', 'icon': 'check', 'text': 'open_marketplace.ui.verified'|trans}, + 'under_verification': {'color': 'yellow', 'icon': 'clock', 'text': 'open_marketplace.ui.under_verification'|trans}, + 'created': {'color': 'blue', 'icon': 'plus', 'text': 'sylius.ui.created'|trans}, + 'rejected': {'color': 'red', 'icon': 'ban', 'text': 'sylius.ui.rejected'|trans} +} %} + + + {{ map[data].text|capitalize }} + diff --git a/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/accept.html.twig b/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/accept.html.twig new file mode 100644 index 0000000..b82b2fc --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/accept.html.twig @@ -0,0 +1,11 @@ +{% if data.status == 'new' %} +
+ +
+ +
+ +
+{% endif %} diff --git a/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/editProductListing.html.twig b/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/editProductListing.html.twig new file mode 100644 index 0000000..a336648 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/editProductListing.html.twig @@ -0,0 +1,7 @@ +{% import '@SyliusUi/Macro/buttons.html.twig' as buttons %} + +{% set path = options.link.url|default(path(options.link.route|default(grid.requestConfiguration.getRouteName('update')), options.link.parameters|default({'id': data.id}))) %} + +{% if data.latestDraft.status != 'under_verification' %} + {{ buttons.default(path, 'open_marketplace.ui.edit', data.id, 'pencil', options.class is defined ? options.class : '') }} +{% endif %} diff --git a/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/productListingDropdown.html.twig b/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/productListingDropdown.html.twig new file mode 100644 index 0000000..ab35d37 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/productListingDropdown.html.twig @@ -0,0 +1,41 @@ +{% import '@SyliusUi/Macro/buttons.html.twig' as buttons %} + +{% if data.latestDraft.status != 'under_verification' %} +
+ +
+{% endif %} diff --git a/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/productReviewDropdown.html.twig b/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/productReviewDropdown.html.twig new file mode 100644 index 0000000..bb008f9 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/productReviewDropdown.html.twig @@ -0,0 +1,34 @@ +{% import '@SyliusUi/Macro/buttons.html.twig' as buttons %} + +
+ +
diff --git a/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/rejectProductListing.html.twig b/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/rejectProductListing.html.twig new file mode 100644 index 0000000..047f0d6 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/rejectProductListing.html.twig @@ -0,0 +1,7 @@ +{% set path = path('open_marketplace_admin_product_listing_reject', { 'id': productListing.id }) %} + +
+ +
diff --git a/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/withdraw.html.twig b/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/withdraw.html.twig new file mode 100644 index 0000000..d3ac867 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Vendor/Action/withdraw.html.twig @@ -0,0 +1,11 @@ +{% if data.vendor.settlementFrequency|default(null) == constant('BitBag\\OpenMarketplace\\Component\\Vendor\\Contracts\\VendorSettlementFrequency::VIRTUAL_WALLET') %} +
+ +
+ +
+ +
+{% endif %} diff --git a/OpenMarketplace/templates/Configuration/Grid/Vendor/Field/money.html.twig b/OpenMarketplace/templates/Configuration/Grid/Vendor/Field/money.html.twig new file mode 100644 index 0000000..4b6a43e --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Vendor/Field/money.html.twig @@ -0,0 +1 @@ +{{ attribute(data, options.vars.method)|sylius_format_money(data.channel.baseCurrency.code, sylius_base_locale) }} diff --git a/OpenMarketplace/templates/Configuration/Grid/Vendor/Field/productListingProductName.html.twig b/OpenMarketplace/templates/Configuration/Grid/Vendor/Field/productListingProductName.html.twig new file mode 100644 index 0000000..3549aac --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Vendor/Field/productListingProductName.html.twig @@ -0,0 +1,15 @@ +{% set product = data.productListing.product %} +{% if product is same as null%} + + {{ data.getName(current_locale()) }} + +{% else %} + {% set slug = data.getSlug(current_locale()) %} + {% if slug != '' %} + + {{ data.getName(current_locale()) }} + + {% else %} + {{ 'N/A (' ~ 'open_marketplace.ui.missing_translation'|trans ~ ')' }} + {% endif %} +{% endif %} diff --git a/OpenMarketplace/templates/Configuration/Grid/Vendor/Field/productListingVerifiedAt.html.twig b/OpenMarketplace/templates/Configuration/Grid/Vendor/Field/productListingVerifiedAt.html.twig new file mode 100644 index 0000000..e88d0e2 --- /dev/null +++ b/OpenMarketplace/templates/Configuration/Grid/Vendor/Field/productListingVerifiedAt.html.twig @@ -0,0 +1,5 @@ +{% if data is not null %} + {{ data | date }} +{% else %} + N/A +{% endif %} diff --git a/OpenMarketplace/templates/Context/Admin/Conversation/_applicant.html.twig b/OpenMarketplace/templates/Context/Admin/Conversation/_applicant.html.twig new file mode 100755 index 0000000..ba72a06 --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Conversation/_applicant.html.twig @@ -0,0 +1,15 @@ +{% set userRole = '' %} +{% for role in data.roles %} + {% set userRole = role %} +{% endfor %} +
+ {% if userRole is same as 'ROLE_VENDOR' %} + {{ data.vendor.companyName }} + {% else %} + {{ data.customer.firstName }} {{ data.customer.lastName }} + {% endif %} +
+
+ {{ 'open_marketplace.ui.conversations_listing.username'|trans }}: {{ data.username }} +
+ diff --git a/OpenMarketplace/templates/Context/Admin/Conversation/_archiveConversation.html.twig b/OpenMarketplace/templates/Context/Admin/Conversation/_archiveConversation.html.twig new file mode 100755 index 0000000..9ff77cd --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Conversation/_archiveConversation.html.twig @@ -0,0 +1,9 @@ +{% if data.isClosed() == false %} +
+ + + +
+{% endif %} diff --git a/OpenMarketplace/templates/Context/Admin/Conversation/_category.html.twig b/OpenMarketplace/templates/Context/Admin/Conversation/_category.html.twig new file mode 100755 index 0000000..3c85035 --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Conversation/_category.html.twig @@ -0,0 +1,13 @@ +{% if data.name is defined %} +
+ + {{ data.name }} + +
+{% else %} +
+ + {{ 'category'|trans }} + +
+{% endif %} diff --git a/OpenMarketplace/templates/Context/Admin/Conversation/create.html.twig b/OpenMarketplace/templates/Context/Admin/Conversation/create.html.twig new file mode 100755 index 0000000..5be8dbd --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Conversation/create.html.twig @@ -0,0 +1,7 @@ +{% extends '@SyliusAdmin/layout.html.twig' %} + +{% form_theme form '@SyliusAdmin/Form/theme.html.twig' %} + +{% block content %} + {% include "Context/Common/Conversation/_createConversationForm.html.twig" %} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Admin/Conversation/show.html.twig b/OpenMarketplace/templates/Context/Admin/Conversation/show.html.twig new file mode 100755 index 0000000..bc22850 --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Conversation/show.html.twig @@ -0,0 +1,9 @@ +{% extends '@SyliusAdmin/layout.html.twig' %} + +{% block title %} + {{ 'open_marketplace.ui.conversations'|trans}} | Sylius +{% endblock %} + +{% block content %} + {% include "Context/Common/Conversation/_showConversation.html.twig" %} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Admin/ProductListing/_details.html.twig b/OpenMarketplace/templates/Context/Admin/ProductListing/_details.html.twig new file mode 100644 index 0000000..38203d6 --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/ProductListing/_details.html.twig @@ -0,0 +1,34 @@ +
+
+ {% include 'Context/Admin/ProductListing/details/_details.html.twig' %} + + + + {% include 'Context/Admin/ProductListing/details/_taxons.html.twig' %} +
+
+ {% include 'Context/Admin/ProductListing/details/_channels.html.twig' %} + + + + {% include 'Context/Common/ProductListing/_pricing.html.twig' with { taxCategory: true } %} +
+
+ + +{% include 'Context/Admin/ProductListing/details/_moreDetails.html.twig' %} + + +{% include 'Context/Admin/ProductListing/details/_shipping.html.twig' %} + + +{% include 'Context/Admin/ProductListing/details/_media.html.twig' %} + + +{% include 'Context/Admin/ProductListing/details/_attributes.html.twig' %} + +{% if productDraft.status == 'under_verification' %} +
+ + {% include 'Context/Admin/ProductListing/details/_verificationForm.html.twig' %} +{% endif %} diff --git a/OpenMarketplace/templates/Context/Admin/ProductListing/details/_attributes.html.twig b/OpenMarketplace/templates/Context/Admin/ProductListing/details/_attributes.html.twig new file mode 100644 index 0000000..4be934e --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/ProductListing/details/_attributes.html.twig @@ -0,0 +1,49 @@ +{% import '@SyliusUi/Macro/flags.html.twig' as flags %} +
+

{{ 'sylius.ui.attributes'|trans }}

+
+ {% if productDraft.attributes|length == 0 %} + {{ 'open_marketplace.ui.no_draft_attributes'|trans }} + {% else %} + + {% for locale in setLocales %} + {% set data_tab = (locale is not null ? locale|sylius_locale_name : 'non-translatable') %} +
+ + + {% for attributeValue in productDraft.attributes|filter(attributeValue => attributeValue.localeCode == locale) %} + + + + + {% endfor %} + +
+ {{ attributeValue.name }} + + {% include [ + '@SyliusAdmin/Product/Show/Types/' ~ attributeValue.type ~ '.html.twig', + '@SyliusAttribute/Types/' ~ attributeValue.type ~ '.html.twig', + '@SyliusAdmin/Product/Show/Types/default.html.twig' + ] with { + 'attribute': attributeValue + } %} +
+
+ {% endfor %} + {% endif %} +
+
diff --git a/OpenMarketplace/templates/Context/Admin/ProductListing/details/_channels.html.twig b/OpenMarketplace/templates/Context/Admin/ProductListing/details/_channels.html.twig new file mode 100644 index 0000000..f4712a2 --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/ProductListing/details/_channels.html.twig @@ -0,0 +1,16 @@ +
+

{{ 'open_marketplace.ui.enabled_channels'|trans }}

+
+ + + {% for channel in productDraft.channels %} + + + + {% endfor %} + +
+ {{ channel.code|sylius_channel_name }} +
+
+
diff --git a/OpenMarketplace/templates/Context/Admin/ProductListing/details/_details.html.twig b/OpenMarketplace/templates/Context/Admin/ProductListing/details/_details.html.twig new file mode 100644 index 0000000..42fb1ec --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/ProductListing/details/_details.html.twig @@ -0,0 +1,44 @@ +
+

{{ 'open_marketplace.ui.details'|trans }}

+
+ + + + + + + + + + + + + + + + + + + +
{{ 'open_marketplace.ui.vendor'|trans }} + {% set vendor = productDraft.productListing.vendor %} + + {{ vendor.companyName ~ ' ' ~ vendor.shopUser.customer.fullName }} + +
{{ 'open_marketplace.ui.name'|trans }} + {{ productDraft.code }} +
{{ 'open_marketplace.ui.published_at'|trans }} + {{ productDraft.publishedAt | date }} +
{{ 'open_marketplace.ui.status'|trans }} + {% if productDraft.status == 'rejected' %} + {{ 'open_marketplace.ui.rejected'|trans }} + {% elseif productDraft.status == 'under_verification' %} + {{ 'open_marketplace.ui.under_verification'|trans }} + {% elseif productDraft.status == 'verified' %} + {{ 'open_marketplace.ui.verified'|trans }} + {% else %} + {{ 'open_marketplace.ui.created'|trans }} + {% endif %} +
+
+
diff --git a/OpenMarketplace/templates/Context/Admin/ProductListing/details/_media.html.twig b/OpenMarketplace/templates/Context/Admin/ProductListing/details/_media.html.twig new file mode 100644 index 0000000..a82ccce --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/ProductListing/details/_media.html.twig @@ -0,0 +1,27 @@ +{% if productDraft.images|length == 0 %} +
+

{{ 'sylius.ui.media'|trans }}

+
+ {{ 'open_marketplace.ui.no_media_uploaded'|trans }} +
+
+{% else %} +
+
+ + {{ 'sylius.ui.media'|trans }} +
+
+
+ {% for image in productDraft.images %} + {% set path = image.path is not null ? image.path|imagine_filter('sylius_admin_product_small_thumbnail') : asset('assets/admin/img/200x200.png') %} +
+ + + +
+ {% endfor %} +
+
+
+{% endif %} diff --git a/OpenMarketplace/templates/Context/Admin/ProductListing/details/_moreDetails.html.twig b/OpenMarketplace/templates/Context/Admin/ProductListing/details/_moreDetails.html.twig new file mode 100644 index 0000000..5bc8c57 --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/ProductListing/details/_moreDetails.html.twig @@ -0,0 +1,42 @@ +

{{ 'sylius.ui.translations'|trans }}

+
+
+ {% for translation in productDraft.translations %} +
+ + + {{ translation.locale|sylius_locale_name }} +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ 'sylius.ui.name'|trans }}{{ translation.name }}
{{ 'sylius.ui.slug'|trans }}{{ translation.slug }}
{{ 'sylius.ui.description'|trans }}{{ translation.description|nl2br }}
{{ 'sylius.ui.meta_keywords'|trans }}{{ translation.metaKeywords }}
{{ 'sylius.ui.meta_description'|trans }}{{ translation.metaDescription }}
{{ 'sylius.ui.short_description'|trans }}{{ translation.shortDescription }}
+
+ {% endfor %} +
+
diff --git a/OpenMarketplace/templates/Context/Admin/ProductListing/details/_shipping.html.twig b/OpenMarketplace/templates/Context/Admin/ProductListing/details/_shipping.html.twig new file mode 100644 index 0000000..7d9fd39 --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/ProductListing/details/_shipping.html.twig @@ -0,0 +1,29 @@ +
+

{{ 'open_marketplace.ui.shipping_details'|trans }}

+
+ + + + + + + + + + + +
{{ 'open_marketplace.ui.is_shipping_required'|trans }} + {% if productDraft.shippingRequired %} + {{ 'open_marketplace.ui.yes'|trans }} + {% else %} + {{ 'open_marketplace.ui.no'|trans }} + {% endif %} +
{{ 'open_marketplace.ui.shipping_category'|trans }} + {% if productDraft.shippingCategory is not null %} + {{ productDraft.shippingCategory.name }} + {% else %} + {{ 'open_marketplace.ui.none'|trans }} + {% endif %} +
+
+
diff --git a/OpenMarketplace/templates/Context/Admin/ProductListing/details/_taxons.html.twig b/OpenMarketplace/templates/Context/Admin/ProductListing/details/_taxons.html.twig new file mode 100644 index 0000000..71b7d3f --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/ProductListing/details/_taxons.html.twig @@ -0,0 +1,30 @@ +
+

{{ 'sylius.ui.taxonomy'|trans }}

+
+ {% if productDraft.mainTaxon == null and productDraft.productDraftTaxons|length == 0 %} + {{ 'open_marketplace.ui.no_draft_taxons'|trans }} + {% else %} + + + {% if productDraft.mainTaxon != null %} + + + + + {% endif %} + + + + + +
{{ 'sylius.ui.main_taxon'|trans }}{{ productDraft.mainTaxon.getFullName }}
{{ 'sylius.ui.product_taxons'|trans }} +
    + {% for productDraftTaxon in productDraft.productDraftTaxons %} +
  • {{ productDraftTaxon.getTaxon.getFullName }}
  • + {% endfor %} +
+
+ {% endif %} +
+
+ diff --git a/OpenMarketplace/templates/Context/Admin/ProductListing/details/_verificationForm.html.twig b/OpenMarketplace/templates/Context/Admin/ProductListing/details/_verificationForm.html.twig new file mode 100644 index 0000000..7bdfc1b --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/ProductListing/details/_verificationForm.html.twig @@ -0,0 +1,34 @@ +

{{ 'open_marketplace.ui.rejection_details'|trans }}

+
+ {{ form_start(form, { attr: { class: 'ui form', id: 'reject-form'}}) }} +
+
+
+ {{ form_row(form.category) }} + {{ form_row(form.messages.vars.prototype.content) }} +
+
+ {{ form_row(form.messages.vars.prototype.file) }} +
+ {{ form_row(form._token) }} +
+
+ + + + {{ form_end(form, { 'render_rest': false }) }} + +
+ + +
+ + +
diff --git a/OpenMarketplace/templates/Context/Admin/ProductListing/show.html.twig b/OpenMarketplace/templates/Context/Admin/ProductListing/show.html.twig new file mode 100644 index 0000000..d157498 --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/ProductListing/show.html.twig @@ -0,0 +1,10 @@ +{% extends '@SyliusAdmin/layout.html.twig' %} + +{% block title %} + {{ 'open_marketplace.ui.product_listing'|trans}} | Sylius +{% endblock %} + +{% block content %} + {% include 'Context/Admin/ProductListing/_details.html.twig' %} +{% endblock %} + diff --git a/OpenMarketplace/templates/Context/Admin/Settlement/Show/_breadcrumb.html.twig b/OpenMarketplace/templates/Context/Admin/Settlement/Show/_breadcrumb.html.twig new file mode 100644 index 0000000..439f3a6 --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Settlement/Show/_breadcrumb.html.twig @@ -0,0 +1,10 @@ +{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} + +{% set breadcrumbs = [ + { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, + { label: 'open_marketplace.ui.settlements'|trans, url: path('open_marketplace_admin_settlement_index') }, + { label: settlement.vendor.companyName, url: path('open_marketplace_admin_settlement_index', {'criteria': {'vendor': settlement.vendor.id}}) }, + { label: settlement.id } +] %} + +{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/OpenMarketplace/templates/Context/Admin/Settlement/Show/_header.html.twig b/OpenMarketplace/templates/Context/Admin/Settlement/Show/_header.html.twig new file mode 100644 index 0000000..058b827 --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Settlement/Show/_header.html.twig @@ -0,0 +1,19 @@ + diff --git a/OpenMarketplace/templates/Context/Admin/Settlement/ShowOrders/_breadcrumb.html.twig b/OpenMarketplace/templates/Context/Admin/Settlement/ShowOrders/_breadcrumb.html.twig new file mode 100644 index 0000000..107c4b6 --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Settlement/ShowOrders/_breadcrumb.html.twig @@ -0,0 +1,11 @@ +{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} + +{% set breadcrumbs = [ + { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, + { label: 'open_marketplace.ui.settlements'|trans, url: path('open_marketplace_admin_settlement_index') }, + { label: settlement.vendor.companyName, url: path('open_marketplace_admin_settlement_index', {'criteria': {'vendor': settlement.vendor.id}}) }, + { label: settlement.id, url: path('open_marketplace_admin_settlement_show', {'id': settlement.id}) }, + { label: 'sylius.ui.orders'|trans } +] %} + +{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/OpenMarketplace/templates/Context/Admin/Settlement/ShowOrders/_header.html.twig b/OpenMarketplace/templates/Context/Admin/Settlement/ShowOrders/_header.html.twig new file mode 100644 index 0000000..c5e2355 --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Settlement/ShowOrders/_header.html.twig @@ -0,0 +1,12 @@ + diff --git a/OpenMarketplace/templates/Context/Admin/Settlement/show.html.twig b/OpenMarketplace/templates/Context/Admin/Settlement/show.html.twig new file mode 100644 index 0000000..28224e6 --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Settlement/show.html.twig @@ -0,0 +1,11 @@ +{% extends '@SyliusAdmin/layout.html.twig' %} +{% block title %}{{ 'open_marketplace.ui.settlement'|trans }} | {{ settlement.vendor.companyName }}{% endblock %} + +{% block content %} + {% include 'Context/Admin/Settlement/Show/_header.html.twig' %} +
+
+ {{ sylius_template_event('open_marketplace.admin.settlement.show.details', _context) }} +
+
+{% endblock %} diff --git a/OpenMarketplace/templates/Context/Admin/Settlement/showOrders.html.twig b/OpenMarketplace/templates/Context/Admin/Settlement/showOrders.html.twig new file mode 100644 index 0000000..fe6349f --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Settlement/showOrders.html.twig @@ -0,0 +1,11 @@ +{% extends '@SyliusAdmin/layout.html.twig' %} +{% block title %}{{ 'open_marketplace.ui.settlement'|trans }} | {{ settlement.vendor.companyName }}{% endblock %} + +{% block content %} + {% include 'Context/Admin/Settlement/ShowOrders/_header.html.twig' %} +
+
+ {{ sylius_template_event('open_marketplace.admin.settlement.show_orders.details', _context) }} +
+
+{% endblock %} diff --git a/OpenMarketplace/templates/Context/Admin/Vendor/Show/_breadcrumb.html.twig b/OpenMarketplace/templates/Context/Admin/Vendor/Show/_breadcrumb.html.twig new file mode 100644 index 0000000..1b96f9c --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Vendor/Show/_breadcrumb.html.twig @@ -0,0 +1,9 @@ +{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} + +{% set breadcrumbs = [ + { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, + { label: 'open_marketplace.ui.vendors'|trans, url: path('open_marketplace_admin_vendor_index') }, + { label: resource.name|default(resource.code|default(resource.companyName)) } +] %} + +{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/OpenMarketplace/templates/Context/Admin/Vendor/Show/_header.html.twig b/OpenMarketplace/templates/Context/Admin/Vendor/Show/_header.html.twig new file mode 100644 index 0000000..63028d7 --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Vendor/Show/_header.html.twig @@ -0,0 +1,16 @@ + diff --git a/OpenMarketplace/templates/Context/Admin/Vendor/Show/_verifyButton.html.twig b/OpenMarketplace/templates/Context/Admin/Vendor/Show/_verifyButton.html.twig new file mode 100644 index 0000000..e5027c6 --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Vendor/Show/_verifyButton.html.twig @@ -0,0 +1,10 @@ +{% if vendor.status == constant('BitBag\\OpenMarketplace\\Component\\Vendor\\Entity\\VendorInterface::STATUS_UNVERIFIED') %} +
+ + + +
+{% endif %} + diff --git a/OpenMarketplace/templates/Context/Admin/Vendor/Update/_breadcrumb.html.twig b/OpenMarketplace/templates/Context/Admin/Vendor/Update/_breadcrumb.html.twig new file mode 100644 index 0000000..1b2ec2d --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Vendor/Update/_breadcrumb.html.twig @@ -0,0 +1,10 @@ +{% import '@SyliusAdmin/Macro/breadcrumb.html.twig' as breadcrumb %} + +{% set breadcrumbs = [ + { label: 'sylius.ui.administration'|trans, url: path('sylius_admin_dashboard') }, + { label: 'open_marketplace.ui.vendors'|trans, url: path('open_marketplace_admin_vendor_index') }, + { label: resource.name|default(resource.code|default(resource.companyName)) }, + { label: 'open_marketplace.ui.edit'|trans } +] %} + +{{ breadcrumb.crumble(breadcrumbs) }} diff --git a/OpenMarketplace/templates/Context/Admin/Vendor/Update/_header.html.twig b/OpenMarketplace/templates/Context/Admin/Vendor/Update/_header.html.twig new file mode 100644 index 0000000..150c297 --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Vendor/Update/_header.html.twig @@ -0,0 +1,12 @@ + diff --git a/OpenMarketplace/templates/Context/Admin/Vendor/show.html.twig b/OpenMarketplace/templates/Context/Admin/Vendor/show.html.twig new file mode 100644 index 0000000..597cfcb --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Vendor/show.html.twig @@ -0,0 +1,12 @@ +{% extends '@SyliusAdmin/layout.html.twig' %} + +{% block title %}{{ 'open_marketplace.ui.vendor'|trans }} | {{ vendor.companyName }}{% endblock %} + +{% block content %} + {% include 'Context/Admin/Vendor/Show/_header.html.twig' %} +
+
+ {{ sylius_template_event('open_marketplace.admin.vendor.show.details', _context) }} +
+
+{% endblock %} diff --git a/OpenMarketplace/templates/Context/Admin/Vendor/update.html.twig b/OpenMarketplace/templates/Context/Admin/Vendor/update.html.twig new file mode 100644 index 0000000..d7fea8b --- /dev/null +++ b/OpenMarketplace/templates/Context/Admin/Vendor/update.html.twig @@ -0,0 +1,25 @@ +{% extends '@SyliusAdmin/layout.html.twig' %} + +{% set header = configuration.vars.header|default(metadata.applicationName~'.ui.edit_'~metadata.name) %} +{% set event_prefix = metadata.applicationName ~ '.admin.' ~ metadata.name ~ '.update' %} + +{% block title %}{{ header|trans }} {{ parent() }}{% endblock %} + +{% form_theme form '@SyliusAdmin/Form/theme.html.twig' %} + +{% block content %} + {% include 'Context/Admin/Vendor/Update/_header.html.twig' %} + {{ sylius_template_event('open_marketplace.admin.vendor.form', _context) }} +{% endblock %} + +{% block stylesheets %} + {{ parent() }} + + {{ sylius_template_event([event_prefix ~ '.stylesheets', 'sylius.admin.update.stylesheets'], { 'metadata': metadata }) }} +{% endblock %} + +{% block javascripts %} + {{ parent() }} + + {{ sylius_template_event([event_prefix ~ '.javascripts', 'sylius.admin.update.javascripts'], { 'metadata': metadata }) }} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Common/Conversation/_archiveRequestMessage.html.twig b/OpenMarketplace/templates/Context/Common/Conversation/_archiveRequestMessage.html.twig new file mode 100755 index 0000000..9b197fa --- /dev/null +++ b/OpenMarketplace/templates/Context/Common/Conversation/_archiveRequestMessage.html.twig @@ -0,0 +1,24 @@ +
+
+ {{ 'open_marketplace.ui.conversation.archive_request_text_first_line'|trans }}
+ {{ 'open_marketplace.ui.conversation.archive_request_text_second_line'|trans }} +
+ +
+
+ + + + + {% if conversation.isClosed() == false and app.user is not same as message.author %} + + {% endif %} + + +
+
+
diff --git a/OpenMarketplace/templates/Context/Common/Conversation/_createConversationForm.html.twig b/OpenMarketplace/templates/Context/Common/Conversation/_createConversationForm.html.twig new file mode 100755 index 0000000..995414e --- /dev/null +++ b/OpenMarketplace/templates/Context/Common/Conversation/_createConversationForm.html.twig @@ -0,0 +1,43 @@ +
+
+

+ +
+ {{ 'open_marketplace.ui.create_new_conversation_header'|trans }} +
+

+
+
+
+ +
+ {{ form_start(form, { attr: { class: 'ui form'}}) }} + {{ form_errors(form) }} +
+
+ {% if form.category is defined %} + {{ form_row(form.category) }} +
+ {% endif %} + + {% if form.vendorUser is defined %} + +
+ {% endif %} + + {{ form_row(form.messages.vars.prototype.content) }} +
+
+ {{ form_row(form.messages.vars.prototype.file) }} +
+ {{ form_row(form._token) }} +
+ {{ form_widget(form.messages.vars.prototype.submit, { attr: { class: 'ui primary button' }}) }} +
+
+ + {{ form_end(form, { 'render_rest': false }) }} +
diff --git a/OpenMarketplace/templates/Context/Common/Conversation/_showConversation.html.twig b/OpenMarketplace/templates/Context/Common/Conversation/_showConversation.html.twig new file mode 100755 index 0000000..ceacdb6 --- /dev/null +++ b/OpenMarketplace/templates/Context/Common/Conversation/_showConversation.html.twig @@ -0,0 +1,145 @@ +{% import '@SyliusUi/Macro/messages.html.twig' as messages %} + +{% block content %} + {% set messagePath = app.request.requestUri ~ "/message/add" %} + +
+
+

+ +
+ {% if app.user.vendor is not defined %} + {{ 'open_marketplace.ui.conversation.user_conversation'|trans }}: + {% else %} + {{ 'open_marketplace.ui.conversation.admin_conversation'|trans }}: + {% endif %} + {% if conversation.category is not null %} + {{ conversation.category.name|lower }} + {% endif %} +
+ {{ 'open_marketplace.ui.conversation.with'|trans }} + {% if conversation.messages.first.adminUser is not null %} + {{ 'open_marketplace.ui.admin'|trans }} + {% else %} + {{ conversation.messages.first.shopUser.username }} + {% endif %} +
+
+

+ {% if conversation.rejectedListingURL %} +
+ {{ 'open_marketplace.ui.rejected_listing_msg'|trans }} + + {{ conversation.rejectedListingURL }} + +
+ {% endif %} +
+
+ +
+ + {% if conversation.isClosed() %} + {{ messages.info('open_marketplace.ui.conversations_listing.reading_closed_conversation') }} + {% endif %} + +
+ {% for message in conversation.messages %} + {% if app.user is same as message.author %} +
+ {% if message.content|raw is same as "ARCHIVE_REQUEST_MESSAGE" %} +
+ +
+ {% include "Context/Common/Conversation/_archiveRequestMessage.html.twig" %} +
+
+ {% else %} +
+ +
+
+ {% if message.author.firstName is defined %} + {{ message.author.firstName ~ ' ' ~ message.author.lastName }} + {% else %} + {{ message.author.username }} + {% endif %} +
+

{{ message.content|raw }}

+
+
+ {{ message.createdAt|date }} + {% if message.filename is not null %} +
+ {{ 'open_marketplace.ui.conversation.attachment'|trans }}: + {{ 'open_marketplace.ui.form.conversation_message.file'|trans }} +
+ {% endif %} +
+
+ {% endif %} +
+

+ {% else %} +

+
+ {% if message.content|raw is same as "ARCHIVE_REQUEST_MESSAGE" %} +
+ +
+ {% include "Context/Common/Conversation/_archiveRequestMessage.html.twig" %} +
+
+ {% else %} +
+ +
+
+ {% if message.author.firstName is defined %} + {{ message.author.firstName ~ ' ' ~ message.author.lastName }} + {% else %} + {{ message.author.username }} + {% endif %} +
+

{{ message.content|raw }}

+
+
+ {{ message.createdAt|date }} + {% if message.filename is not null %} +
+ {{ 'open_marketplace.ui.conversation.attachment'|trans }}: + {{ 'open_marketplace.ui.form.conversation_message.file'|trans }} +
+ {% endif %} +
+
+ {% endif %} +
+ {% endif %} + {% endfor %} +
+ + {% if conversation.isOpen() %} +
+
+ {{ 'open_marketplace.ui.conversation.your_response_header'|trans }} +
+
+ + {{ form_start(form, { 'action': messagePath, attr: { class: 'ui form' } }) }} +
+
+ {{ form_row(form.content) }} +
+
+ {{ form_row(form.file) }} +
+ {{ form_row(form._token) }} +
+ {{ form_widget(form.submit, { attr: { class: 'ui primary button' } }) }} +
+
+ {{ form_end(form, { 'render_rest': false }) }} +
+ {% endif %} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Common/ProductListing/_pricing.html.twig b/OpenMarketplace/templates/Context/Common/ProductListing/_pricing.html.twig new file mode 100644 index 0000000..82b2250 --- /dev/null +++ b/OpenMarketplace/templates/Context/Common/ProductListing/_pricing.html.twig @@ -0,0 +1,11 @@ +
+

{{ 'sylius.ui.pricing'|trans }}

+
+ + {% include 'Context/Common/ProductListing/details/_pricingTable.html.twig' %} + + {% if taxCategory is defined %} + {% include 'Context/Common/ProductListing/details/_taxCategory.html.twig' %} + {% endif %} +
+
diff --git a/OpenMarketplace/templates/Context/Common/ProductListing/details/_pricingTable.html.twig b/OpenMarketplace/templates/Context/Common/ProductListing/details/_pricingTable.html.twig new file mode 100644 index 0000000..52c83d5 --- /dev/null +++ b/OpenMarketplace/templates/Context/Common/ProductListing/details/_pricingTable.html.twig @@ -0,0 +1,28 @@ +{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} + + + + + + + + + + + {% for channelPricing in productDraft.productListingPrices %} + {% set channel = get_channel(channelPricing.channelCode) %} + + + + + {% if channelPricing.originalPrice != null %} + + {% else %} + + {% endif %} + + {% endfor %} + +
{{ 'sylius.ui.channels'|trans }}{{ 'sylius.ui.price'|trans }}{{ 'sylius.ui.original_price'|trans }}
+ {{ channelPricing.channelCode|sylius_channel_name }} + {{ money.format(channelPricing.price, channel.baseCurrency.code) }}{{ money.format(channelPricing.originalPrice, channel.baseCurrency.code) }}N/A
diff --git a/OpenMarketplace/templates/Context/Common/ProductListing/details/_taxCategory.html.twig b/OpenMarketplace/templates/Context/Common/ProductListing/details/_taxCategory.html.twig new file mode 100644 index 0000000..0b25026 --- /dev/null +++ b/OpenMarketplace/templates/Context/Common/ProductListing/details/_taxCategory.html.twig @@ -0,0 +1,16 @@ +
+ + + + + + + + +
+ + {{ 'open_marketplace.ui.tax_category'|trans }} + + + {{ productDraft.taxCategory|default('-') }} +
diff --git a/OpenMarketplace/templates/Context/Shop/Cart/Summary/_item.html.twig b/OpenMarketplace/templates/Context/Shop/Cart/Summary/_item.html.twig new file mode 100644 index 0000000..5a41002 --- /dev/null +++ b/OpenMarketplace/templates/Context/Shop/Cart/Summary/_item.html.twig @@ -0,0 +1,32 @@ +{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} + +{% set product_variant = item.variant %} +{% set original_price_to_display = sylius_order_item_original_price_to_display(item) %} + + + + {% include '@SyliusShop/Product/_info.html.twig' with {'variant': product_variant} %} + + + + {% if original_price_to_display is not null %} + + {{ money.convertAndFormat(original_price_to_display) }} + + {% endif %} + {{ money.convertAndFormat(item.discountedUnitPrice) }} + + + {{ form_row(form.quantity, sylius_test_form_attribute('cart-item-quantity-input', item.productName)|sylius_merge_recursive({'attr': {'form': main_form}})) }} + + +
+ + + +
+ + + {{ money.convertAndFormat(item.subtotal) }} + + diff --git a/OpenMarketplace/templates/Context/Shop/Checkout/SelectShipping/_form.html.twig b/OpenMarketplace/templates/Context/Shop/Checkout/SelectShipping/_form.html.twig new file mode 100644 index 0000000..e4d85a9 --- /dev/null +++ b/OpenMarketplace/templates/Context/Shop/Checkout/SelectShipping/_form.html.twig @@ -0,0 +1,7 @@ +
+ {% for key, shipment in order.shipments %} + {% include 'Context/Shop/Checkout/SelectShipping/_shipment.html.twig' with {'form': form.shipments[key]} %} + {% else %} + {% include '@SyliusShop/Checkout/SelectShipping/_unavailable.html.twig' %} + {% endfor %} +
diff --git a/OpenMarketplace/templates/Context/Shop/Checkout/SelectShipping/_itemUnit.html.twig b/OpenMarketplace/templates/Context/Shop/Checkout/SelectShipping/_itemUnit.html.twig new file mode 100644 index 0000000..2af222a --- /dev/null +++ b/OpenMarketplace/templates/Context/Shop/Checkout/SelectShipping/_itemUnit.html.twig @@ -0,0 +1,24 @@ +{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} + +{% set product_variant = item.variant %} +{% set original_price_to_display = sylius_order_item_original_price_to_display(item) %} + + + + {% include '@SyliusShop/Product/_info.html.twig' with {'variant': product_variant} %} + + + {% if original_price_to_display is not null %} + + {{ money.convertAndFormat(original_price_to_display) }} + + {% endif %} + {{ money.convertAndFormat(item.discountedUnitPrice) }} + + + {{ item.quantity }} + + + {{ money.convertAndFormat(item.subtotal) }} + + diff --git a/OpenMarketplace/templates/Context/Shop/Checkout/SelectShipping/_shipment.html.twig b/OpenMarketplace/templates/Context/Shop/Checkout/SelectShipping/_shipment.html.twig new file mode 100644 index 0000000..9440317 --- /dev/null +++ b/OpenMarketplace/templates/Context/Shop/Checkout/SelectShipping/_shipment.html.twig @@ -0,0 +1,43 @@ +
+ {% if shipment.vendor.companyName is defined %} +
{{ shipment.vendor.companyName }}
+ {% endif %} +
+ {{ form_errors(form.method) }} + + + + + + + + + + + + {% set items = [] %} + {% for key, unit in shipment.units %} + {% set orderItem = unit.orderItem %} + {% if orderItem not in items %} + {% set items = items|merge([orderItem]) %} + {% endif %} + {% endfor %} + + {% for item in items %} + {% if item.variant.shippingRequired %} + {% include 'Context/Shop/Checkout/SelectShipping/_itemUnit.html.twig' with {'item': item} %} + {% endif %} + {% endfor %} + +
{{ 'sylius.ui.item'|trans }}{{ 'sylius.ui.unit_price'|trans }}{{ 'sylius.ui.qty'|trans }}{{ 'sylius.ui.total'|trans }}
+ +
+ {% for key, choice_form in form.method %} + {% set fee = form.method.vars.shipping_costs[choice_form.vars.value] %} + {% set method = form.method.vars.choices[key].data %} + {% include '@SyliusShop/Checkout/SelectShipping/_choice.html.twig' with {'form': choice_form, 'method': method, 'fee': fee} %} + {% else %} + {% include '@SyliusShop/Checkout/SelectShipping/_unavailable.html.twig' %} + {% endfor %} +
+
diff --git a/OpenMarketplace/templates/Context/Shop/Checkout/ThankYouPage/Table/_headers.html.twig b/OpenMarketplace/templates/Context/Shop/Checkout/ThankYouPage/Table/_headers.html.twig new file mode 100644 index 0000000..7ba015c --- /dev/null +++ b/OpenMarketplace/templates/Context/Shop/Checkout/ThankYouPage/Table/_headers.html.twig @@ -0,0 +1,5 @@ + + {{ 'open_marketplace.ui.vendors'|trans }} + {{ 'sylius.ui.item'|trans }} + {{ 'sylius.ui.shipment'|trans }} + diff --git a/OpenMarketplace/templates/Context/Shop/Checkout/ThankYouPage/Table/_item.html.twig b/OpenMarketplace/templates/Context/Shop/Checkout/ThankYouPage/Table/_item.html.twig new file mode 100644 index 0000000..fdf1278 --- /dev/null +++ b/OpenMarketplace/templates/Context/Shop/Checkout/ThankYouPage/Table/_item.html.twig @@ -0,0 +1,22 @@ + + + {% if secondaryOrder.vendor.companyName is defined %} + {{ secondaryOrder.vendor.companyName }} + {% endif %} + + + {% for item in secondaryOrder.items %} + {% if secondaryOrder.items|length > 1 %} + {% if loop.last %} + {% include '@SyliusShop/Product/_info.html.twig' with {'variant': item.variant} %} + {% else %} + {% include '@SyliusShop/Product/_info.html.twig' with {'variant': item.variant} %} +
+ {% endif %} + {% else %} + {% include '@SyliusShop/Product/_info.html.twig' with {'variant': item.variant} %} + {% endif %} + {% endfor %} + + {% include 'Context/Shop/Checkout/ThankYouPage/Table/_shipments.html.twig' %} + diff --git a/OpenMarketplace/templates/Context/Shop/Checkout/ThankYouPage/Table/_items.html.twig b/OpenMarketplace/templates/Context/Shop/Checkout/ThankYouPage/Table/_items.html.twig new file mode 100644 index 0000000..b78401b --- /dev/null +++ b/OpenMarketplace/templates/Context/Shop/Checkout/ThankYouPage/Table/_items.html.twig @@ -0,0 +1,3 @@ +{% for secondaryOrder in order.secondaryOrders %} + {% include 'Context/Shop/Checkout/ThankYouPage/Table/_item.html.twig' %} +{% endfor %} diff --git a/OpenMarketplace/templates/Context/Shop/Checkout/ThankYouPage/Table/_shipments.html.twig b/OpenMarketplace/templates/Context/Shop/Checkout/ThankYouPage/Table/_shipments.html.twig new file mode 100644 index 0000000..bcfc2bc --- /dev/null +++ b/OpenMarketplace/templates/Context/Shop/Checkout/ThankYouPage/Table/_shipments.html.twig @@ -0,0 +1,14 @@ +{% set item = secondaryOrder.items|last %} +{% for shipment in order.shipments %} + {% if shipment.vendor is same as item.productOwner %} + {% set state = shipment.state %} +
+ +
+
+ {{ shipment.method }} +
+
+
+ {% endif %} +{% endfor %} diff --git a/OpenMarketplace/templates/Context/Shop/Checkout/ThankYouPage/_table.html.twig b/OpenMarketplace/templates/Context/Shop/Checkout/ThankYouPage/_table.html.twig new file mode 100644 index 0000000..ced682c --- /dev/null +++ b/OpenMarketplace/templates/Context/Shop/Checkout/ThankYouPage/_table.html.twig @@ -0,0 +1,8 @@ + + + {% include 'Context/Shop/Checkout/ThankYouPage/Table/_headers.html.twig' %} + + + {% include 'Context/Shop/Checkout/ThankYouPage/Table/_items.html.twig' %} + +
diff --git a/OpenMarketplace/templates/Context/Shop/Checkout/selectShipping.html.twig b/OpenMarketplace/templates/Context/Shop/Checkout/selectShipping.html.twig new file mode 100644 index 0000000..ce83571 --- /dev/null +++ b/OpenMarketplace/templates/Context/Shop/Checkout/selectShipping.html.twig @@ -0,0 +1,34 @@ +{% extends '@SyliusShop/Checkout/layout.html.twig' %} + +{% form_theme form '@SyliusShop/Form/theme.html.twig' %} + +{% block title %}{{ 'sylius.ui.shipping'|trans }} | {{ parent() }}{% endblock %} + +{% block content %} + {{ sylius_template_event(['sylius.shop.checkout.select_shipping.steps', 'sylius.shop.checkout.steps'], _context|merge({'active': 'select_shipping', 'orderTotal': order.total})) }} + +
+
+
+ {{ sylius_template_event('sylius.shop.checkout.select_shipping.before_form', {'order': order}) }} + + {{ form_start(form, {'action': path('sylius_shop_checkout_select_shipping'), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }} + {{ form_errors(form) }} + + + {% include 'Context/Shop/Checkout/SelectShipping/_form.html.twig' %} + + + {{ sylius_template_event('sylius.shop.checkout.select_shipping.before_navigation', {'order': order}) }} + + {% include '@SyliusShop/Checkout/SelectShipping/_navigation.html.twig' %} + + {{ form_row(form._token) }} + {{ form_end(form, {'render_rest': false}) }} +
+
+
+ {{ sylius_template_event(['sylius.shop.checkout.select_shipping.sidebar', 'sylius.shop.checkout.sidebar'], _context) }} +
+
+{% endblock %} diff --git a/OpenMarketplace/templates/Context/Shop/Checkout/thankYou.html.twig b/OpenMarketplace/templates/Context/Shop/Checkout/thankYou.html.twig new file mode 100644 index 0000000..8baa2c5 --- /dev/null +++ b/OpenMarketplace/templates/Context/Shop/Checkout/thankYou.html.twig @@ -0,0 +1,44 @@ +{% extends '@SyliusShop/layout.html.twig' %} + +{% block title %}{{ 'sylius.ui.thank_you'|trans }} | {{ parent() }}{% endblock %} + +{% block content %} + +
+
+

+ {% set lastPayment = order.payments.last() %} + +
+ {{ 'sylius.ui.thank_you'|trans }} +
{{ 'sylius.ui.placed_an_order'|trans }}
+
+

+ + {{ sylius_template_event('sylius.shop.order.thank_you.after_message', {'order': order}) }} + + {% if lastPayment != false %} + {% if lastPayment.method.instructions is not null %} +
+ {{ lastPayment.method.instructions }} +
+ {% endif %} + + {% endif %} + + {% if order.customer.user is not null %} + {{ 'open_marketplace.ui.view_orders'|trans }} + {% else %} + {{ 'sylius.ui.change_payment_method'|trans }} + + + {{ 'sylius.ui.create_an_account'|trans }} + + {% endif %} +
+
+ +
+ {% include 'Context/Shop/Checkout/ThankYouPage/_table.html.twig' %} +
+{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/Common/_address.html.twig b/OpenMarketplace/templates/Context/Vendor/Common/_address.html.twig new file mode 100644 index 0000000..c9f6801 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Common/_address.html.twig @@ -0,0 +1,16 @@ +{% import "@SyliusUi/Macro/flags.html.twig" as flags %} + +
+ {{ address.firstName }} {{ address.lastName }} + {% if address.company %} + {{ address.company }}
+ {% endif %} + {{ address.phoneNumber }}
+ {{ address.street }}
+ {{ address.city }}
+ {% if address|sylius_province_name is not empty %} + {{ address|sylius_province_name }}
+ {% endif %} + {{ flags.fromCountryCode(address.countryCode) }} + {{ address.countryCode|sylius_country_name|upper }} {{ address.postcode }} +
diff --git a/OpenMarketplace/templates/Context/Vendor/Common/_breadcrumb.html.twig b/OpenMarketplace/templates/Context/Vendor/Common/_breadcrumb.html.twig new file mode 100644 index 0000000..ff5f194 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Common/_breadcrumb.html.twig @@ -0,0 +1,9 @@ +{% block breadcrumb %} + +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/Conversation/create.html.twig b/OpenMarketplace/templates/Context/Vendor/Conversation/create.html.twig new file mode 100755 index 0000000..a1541c4 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Conversation/create.html.twig @@ -0,0 +1,15 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% block breadcrumb_page %} + {{ 'open_marketplace.ui.conversations_listing.breadcrumb_header'|trans }} +
/
+
{{ 'open_marketplace.ui.create_new_conversation_breadcrumb'|trans }}
+{% endblock %} + +{% form_theme form '@SyliusShop/Form/theme.html.twig' %} + +{% block subcontent %} +
+ {% include "Context/Common/Conversation/_createConversationForm.html.twig" %} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/Conversation/index.html.twig b/OpenMarketplace/templates/Context/Vendor/Conversation/index.html.twig new file mode 100755 index 0000000..d9dd5c1 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Conversation/index.html.twig @@ -0,0 +1,115 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} +{% import '@SyliusUi/Macro/messages.html.twig' as messages %} + +{% block breadcrumb_page %} +
{{ 'open_marketplace.ui.conversations_listing.breadcrumb_header'|trans }}
+{% endblock %} + +{% block subcontent %} +
+
+
+

+ {% if app.request.query.get('closed') %} + +
+ {{ 'open_marketplace.ui.conversations_listing.listing_header_closed'|trans }} +
{{ 'open_marketplace.ui.conversations_listing.your_closed_conversations'|trans }}
+
+ {% else %} + +
+ {{ 'open_marketplace.ui.conversations_listing.listing_header_open'|trans }} +
{{ 'open_marketplace.ui.conversations_listing.your_open_conversations'|trans }}
+
+ {% endif %} +

+
+ +
+ +
+ + {% if account_disabled %} +
+
+ {{ 'sylius.ui.info'|trans }} +
+

+ {{ 'open_marketplace.ui.your_account_has_been_disabled'|trans }} +

+
+
+ {% endif %} + + {% if conversations|length == 0 %} + {% if app.request.query.get('closed') %} + {{ messages.info('open_marketplace.ui.conversations_listing.no_closed_conversations') }} + {% else %} + {{ messages.info('open_marketplace.ui.conversations_listing.no_open_conversations') }} + {% endif %} + {% endif %} + + {% if conversations|length > 0 %} + {% for conversation in conversations %} + + {% endfor %} + {% endif %} +{% endblock %} + + diff --git a/OpenMarketplace/templates/Context/Vendor/Conversation/show.html.twig b/OpenMarketplace/templates/Context/Vendor/Conversation/show.html.twig new file mode 100755 index 0000000..1b644f1 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Conversation/show.html.twig @@ -0,0 +1,27 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% block breadcrumb_page %} + {{ 'open_marketplace.ui.conversations_listing.breadcrumb_header'|trans }} +
/
+ + {% if conversation is not null %} + {% if conversation.category is not null %} +
{{ conversation.category.name }}
+ {% else %} + {% set author = conversation.messages.first.author %} + {% if conversation.messages.first.vendorUser is not null %} +
{{ author.customer.firstName ~ ' ' ~ author.customer.lastName }}
+ {% elseif conversation.messages.first.shopUser is not null %} +
{{ author.username }}
+ {% else %} +
{{ author.firstName ~ ' ' ~ author.lastName }}
+ {% endif %} + {% endif %} + {% endif %} +{% endblock %} + +{% block subcontent %} +
+ {% include "Context/Common/Conversation/_showConversation.html.twig" %} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/Customers/index.html.twig b/OpenMarketplace/templates/Context/Vendor/Customers/index.html.twig new file mode 100644 index 0000000..75da273 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Customers/index.html.twig @@ -0,0 +1,18 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% block title %}{{ 'sylius.ui.order_history'|trans }} | {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} +
{{ 'sylius.ui.customers'|trans }}
+{% endblock %} + +{% block subcontent %} + {% include "Context/Vendor/_header.html.twig" with { + "header": 'open_marketplace.ui.customers', + "subheader": 'open_marketplace.ui.manage_customers', + "icon": 'users' + } %} + + {{ sylius_grid_render(resources, '@SyliusAdmin/Grid/_default.html.twig') }} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/Customers/show.html.twig b/OpenMarketplace/templates/Context/Vendor/Customers/show.html.twig new file mode 100644 index 0000000..6e38f09 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Customers/show.html.twig @@ -0,0 +1,97 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% import '@SyliusUi/Macro/buttons.html.twig' as buttons %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% block title %}{{ 'sylius.ui.customer'|trans }} | {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} + {{ 'sylius.ui.customers'|trans }} +
/
+
{{ resource.id }}
+
/
+
{{ 'sylius.ui.show'|trans }}
+{% endblock %} + +{% block subcontent %} +
+
+
+

+ +
+ {{ customer.fullName|default('sylius.ui.guest_customer'|trans) }} +
+
+
+ {{ customer.email }} +
+ {% if customer.user is null %} +
+ + {{ 'sylius.ui.guest'|trans }} + +
+ {% endif %} +
+
+
+

+
+ {% set menu = knp_menu_get('sylius.vendor.customer.show', [], {'customer': customer}) %} + {{ knp_menu_render(menu, {'template': '@SyliusUi/Menu/top.html.twig'}) }} +
+
+
+
+
+
+
+ {{ customer.fullName|default('sylius.ui.guest_customer'|trans) }} +
+
+ {{ 'sylius.ui.customer_since'|trans }} {{ customer.createdAt|date }} +
+ {% if customer.group is not null %} + {{ 'sylius.ui.group_membership'|trans }}: {{ customer.group }} + {% endif %} +
+
+
+
+ + {{ 'sylius.ui.subscribed_to_newsletter'|trans }} +
+ {% if customer.user is not null %} + {% set user = customer.user %} +
+ + {{ 'sylius.ui.email_verified'|trans }} +
+ {% endif %} +
+
+ + {{ customer.email }} + + {% if customer.phoneNumber is not null %} +
+ {{ customer.phoneNumber }} +
+ {% endif %} +
+
+
+
+

+ {{ 'sylius.ui.default_address'|trans }} +

+
+ {% if customer.defaultAddress is not null %} + {% include 'Context/Vendor/Common/_address.html.twig' with {'address': customer.defaultAddress} %} + {% else %} + {{ 'sylius.ui.this_customer_does_not_have_a_default_address'|trans }} + {% endif %} +
+
+
+{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/DraftAttributes/_menu.html.twig b/OpenMarketplace/templates/Context/Vendor/DraftAttributes/_menu.html.twig new file mode 100644 index 0000000..1f58a5e --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/DraftAttributes/_menu.html.twig @@ -0,0 +1,16 @@ +
+
+ +
+
diff --git a/OpenMarketplace/templates/Context/Vendor/DraftAttributes/attributeTypes.html.twig b/OpenMarketplace/templates/Context/Vendor/DraftAttributes/attributeTypes.html.twig new file mode 100644 index 0000000..4135372 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/DraftAttributes/attributeTypes.html.twig @@ -0,0 +1,7 @@ +{% for name, attributeType in types %} + {% set createRouteName = metadata.applicationName~'_admin_'~metadata.name~'_create' %} + + {% set label = 'sylius.form.attribute_type.' ~ attributeType.type %} + {{ label|trans }} + +{% endfor %} diff --git a/OpenMarketplace/templates/Context/Vendor/DraftAttributes/create.html.twig b/OpenMarketplace/templates/Context/Vendor/DraftAttributes/create.html.twig new file mode 100644 index 0000000..93c41c3 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/DraftAttributes/create.html.twig @@ -0,0 +1,56 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% set header = configuration.vars.header|default(metadata.applicationName~'.ui.new_'~metadata.name) %} +{% set event_prefix = metadata.applicationName ~ '.admin.' ~ metadata.name ~ '.create' %} + +{% block title %}{{ header|trans }} {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} + {{ 'sylius.ui.attributes'|trans }} +
/
+
{{ 'sylius.ui.create'|trans }}
+{% endblock %} + +{% form_theme form '@SyliusAdmin/Form/theme.html.twig' %} + +{% block subcontent %} + {% include "Context/Vendor/_header.html.twig" with { + "header": 'open_marketplace.ui.create_draft_attribute', + "icon": 'tag' + } %} + + {{ form_start(form, {'action': path('open_marketplace_vendor_attributes_create', configuration.vars.route.parameters|default({})), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }} + {% include '@SyliusAdmin/Crud/form_validation_errors_checker.html.twig' %} + + {% if configuration.vars.templates.form is defined %} + {% include configuration.vars.templates.form %} + {% if not form._token.isRendered %} + {{ form_row(form._token) }} + {% endif %} + {% else %} + {{ form_widget(form) }} + {% endif %} + + + {% include '@SyliusUi/Form/Buttons/_create.html.twig' with {'paths': {'cancel': path('open_marketplace_vendor_attributes_index', configuration.vars.route.parameters|default({}))}} %} + + {{ form_end(form, {'render_rest': false}) }} + +{% endblock %} + +{% block topbar %} +{% endblock %} + + +{% block stylesheets %} + {{ parent() }} + + {{ sylius_template_event([event_prefix ~ '.stylesheets', 'sylius.admin.create.stylesheets'], { 'metadata': metadata }) }} +{% endblock %} + +{% block javascripts %} + {{ parent() }} + + {{ sylius_template_event([event_prefix ~ '.javascripts', 'sylius.admin.create.javascripts'], { 'metadata': metadata }) }} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/DraftAttributes/index.html.twig b/OpenMarketplace/templates/Context/Vendor/DraftAttributes/index.html.twig new file mode 100644 index 0000000..02e68a7 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/DraftAttributes/index.html.twig @@ -0,0 +1,20 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% set definition = resources.definition %} +{% block title %}{{ 'open_marketplace.ui.draft_attributes'|trans }} | {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} +
{{ 'sylius.ui.attributes'|trans }}
+{% endblock %} + +{% block subcontent %} + {% include "Context/Vendor/_header.html.twig" with { + "header": 'open_marketplace.ui.draft_attributes', + "subheader": 'open_marketplace.ui.manage_product_listing_attributes', + "icon": 'tag', + "buttons": 'Context/Vendor/DraftAttributes/_menu.html.twig' + } %} + + {{ sylius_grid_render(resources, '@SyliusAdmin/Grid/_default.html.twig') }} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/DraftAttributes/update.html.twig b/OpenMarketplace/templates/Context/Vendor/DraftAttributes/update.html.twig new file mode 100644 index 0000000..b940a8a --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/DraftAttributes/update.html.twig @@ -0,0 +1,57 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% set header = configuration.vars.header|default(metadata.applicationName~'.ui.new_'~metadata.name) %} +{% set event_prefix = metadata.applicationName ~ '.admin.' ~ metadata.name ~ '.create' %} + +{% block title %}{{ header|trans }} {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} + {{ 'sylius.ui.attributes'|trans }} +
/
+
{{ resource.id }}
+
/
+
{{ 'sylius.ui.edit'|trans }}
+{% endblock %} + +{% form_theme form '@SyliusAdmin/Form/theme.html.twig' %} + +{% block subcontent %} + {% include "Context/Vendor/_header.html.twig" with { + "header": 'open_marketplace.ui.edit_draft_attribute', + "icon": 'tag' + } %} + + {{ form_start(form, {'action': path('open_marketplace_product_draft_attribute_update', configuration.vars.route.parameters|default({})), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }} + {% include '@SyliusAdmin/Crud/form_validation_errors_checker.html.twig' %} + + {% if configuration.vars.templates.form is defined %} + {% include configuration.vars.templates.form %} + {% if not form._token.isRendered %} + {{ form_row(form._token) }} + {% endif %} + {% else %} + {{ form_widget(form) }} + {% endif %} + + + {% include '@SyliusUi/Form/Buttons/_create.html.twig' with {'paths': {'cancel': path('open_marketplace_vendor_attributes_index', configuration.vars.route.parameters|default({}))}} %} + + {{ form_end(form, {'render_rest': false}) }} +{% endblock %} + +{% block topbar %} +{% endblock %} + + +{% block stylesheets %} + {{ parent() }} + + {{ sylius_template_event([event_prefix ~ '.stylesheets', 'sylius.admin.create.stylesheets'], { 'metadata': metadata }) }} +{% endblock %} + +{% block javascripts %} + {{ parent() }} + + {{ sylius_template_event([event_prefix ~ '.javascripts', 'sylius.admin.create.javascripts'], { 'metadata': metadata }) }} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/Email/profileUpdate.html.twig b/OpenMarketplace/templates/Context/Vendor/Email/profileUpdate.html.twig new file mode 100644 index 0000000..93242cd --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Email/profileUpdate.html.twig @@ -0,0 +1,21 @@ +{% extends '@SyliusCore/Email/layout.html.twig' %} + +{% block subject %} + {{ 'open_marketplace.email.vendor_profile_update'|trans }} +{% endblock %} + +{% block body %} +
+ {{ 'open_marketplace.email.request_profile_update_greeting' | trans }} +
+
+
+ {{ 'open_marketplace.email.request_profile_update_info' | trans }} +
+
+ +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/Email/settlementsCreated.html.twig b/OpenMarketplace/templates/Context/Vendor/Email/settlementsCreated.html.twig new file mode 100644 index 0000000..63e3c61 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Email/settlementsCreated.html.twig @@ -0,0 +1,30 @@ +{% extends '@SyliusCore/Email/layout.html.twig' %} + +{% block subject %} + {{ 'open_marketplace.email.settlements_created.subject'|trans }} +{% endblock %} + +{% block body %} +
+ {{ 'open_marketplace.email.settlements_created.greetings' | trans }} +
+
+
+ {{ 'open_marketplace.email.settlements_created.info' | trans }} + + + + + + + {% for settlement in settlements %} + + + + + + {% endfor %} +
{{ 'open_marketplace.ui.period'|trans }}{{ 'open_marketplace.ui.channel'|trans }}{{ 'open_marketplace.ui.total_commission_amount'|trans }}
{{ [settlement.startDate|format_date(pattern='dd/MM/YYYY'), settlement.endDate|format_date(pattern='dd/MM/YYYY')]|join(' - ') }}{{ settlement.channelName }}{{ settlement.commissionTotal }}
+
+
+{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/Inventory/index.html.twig b/OpenMarketplace/templates/Context/Vendor/Inventory/index.html.twig new file mode 100644 index 0000000..8eb4ade --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Inventory/index.html.twig @@ -0,0 +1,18 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% block title %}{{ 'sylius.ui.order_history'|trans }} | {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} +
{{ 'sylius.ui.inventory'|trans }}
+{% endblock %} + +{% block subcontent %} + {% include "Context/Vendor/_header.html.twig" with { + "header": 'open_marketplace.ui.inventory', + "subheader": 'open_marketplace.ui.manage_product_listing_stock', + "icon": 'clipboard' + } %} + + {{ sylius_grid_render(resources, '@SyliusShop/Grid/_default.html.twig') }} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/Inventory/update.html.twig b/OpenMarketplace/templates/Context/Vendor/Inventory/update.html.twig new file mode 100644 index 0000000..4922c14 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Inventory/update.html.twig @@ -0,0 +1,61 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% block title %}{{ 'sylius.ui.order_history'|trans }} | {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} + {{ 'sylius.ui.inventory'|trans }} +
/
+
{{ resource.id }}
+
/
+
{{ 'sylius.ui.edit'|trans }}
+{% endblock %} + +{% block subcontent %} + {% include "Context/Vendor/_header.html.twig" with { + "header": 'open_marketplace.ui.edit_inventory', + "icon": 'clipboard' + } %} + +
+

{{ resource.code }}

+ {{ form_start(form, {'action': path('open_marketplace_vendor_inventory_update', { 'id': resource.id }), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }} + + {% include '@SyliusAdmin/Crud/form_validation_errors_checker.html.twig' %} + + {% if not form._token.isRendered %} + {{ form_row(form._token) }} + {% endif %} + +
+
+ {{ form_row(form.onHand) }} +
+
+
+ {{ form_widget(form.tracked) }} + +
+
+
+ +
+ {{ form_end(form, {'render_rest': true}) }} +
+
+{% endblock %} + +{% block stylesheets %} + {{ parent() }} + + {{ sylius_template_event(['sylius.admin.product_variant.stylesheets', 'sylius.admin.update.stylesheets'], { 'metadata': metadata }) }} +{% endblock %} +{% block javascripts %} + {{ parent() }} + + {{ sylius_template_event(['sylius.admin.product_variant.javascripts', 'sylius.admin.update.javascripts'], { 'metadata': metadata }) }} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/Login/_vendorDefaultCredentials.html.twig b/OpenMarketplace/templates/Context/Vendor/Login/_vendorDefaultCredentials.html.twig new file mode 100644 index 0000000..5231001 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Login/_vendorDefaultCredentials.html.twig @@ -0,0 +1,25 @@ +
+
{{ 'open_marketplace.ui.vendor_test_credentials'|trans }}

+
+
+

+ {{ 'open_marketplace.ui.username'|trans }}: camille@example.com + {{ 'open_marketplace.ui.password'|trans }}: password +

+

+ {{ 'open_marketplace.ui.username'|trans }}: good-and-better@example.com + {{ 'open_marketplace.ui.password'|trans }}: password +

+
+
+

+ {{ 'open_marketplace.ui.username'|trans }}: lisa-comp@example.com + {{ 'open_marketplace.ui.password'|trans }}: password +

+

+ {{ 'open_marketplace.ui.username'|trans }}: health@example.com + {{ 'open_marketplace.ui.password'|trans }}: password +

+
+
+
diff --git a/OpenMarketplace/templates/Context/Vendor/Order/Partials/Shippings/_cancelled.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/Partials/Shippings/_cancelled.html.twig new file mode 100644 index 0000000..6e7decf --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/Partials/Shippings/_cancelled.html.twig @@ -0,0 +1,4 @@ + + + {{ 'sylius.ui.cancelled'|trans }} + \ No newline at end of file diff --git a/OpenMarketplace/templates/Context/Vendor/Order/Partials/Shippings/_partiallyShipped.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/Partials/Shippings/_partiallyShipped.html.twig new file mode 100644 index 0000000..1bd6e05 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/Partials/Shippings/_partiallyShipped.html.twig @@ -0,0 +1,4 @@ + + + {{ 'sylius.ui.partially_shipped'|trans }} + \ No newline at end of file diff --git a/OpenMarketplace/templates/Context/Vendor/Order/Partials/Shippings/_ready.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/Partials/Shippings/_ready.html.twig new file mode 100644 index 0000000..cd9f001 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/Partials/Shippings/_ready.html.twig @@ -0,0 +1,4 @@ + + + {{ 'sylius.ui.ready'|trans }} + \ No newline at end of file diff --git a/OpenMarketplace/templates/Context/Vendor/Order/Partials/Shippings/_shipmentsForm.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/Partials/Shippings/_shipmentsForm.html.twig new file mode 100644 index 0000000..4cd73d2 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/Partials/Shippings/_shipmentsForm.html.twig @@ -0,0 +1,10 @@ +
+ {{ form_start(form, {'action': path('open_marketplace_vendor_orders_shipment_ship', {'id': shipment.id, 'orderId': order.id}), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }} + +
+ {{ form_widget(form.tracking, {'attr': {'placeholder': 'sylius.ui.tracking_code'|trans ~ '...'}}) }} + +
+ {{ form_row(form._token) }} + {{ form_end(form, {'render_rest': false}) }} +
diff --git a/OpenMarketplace/templates/Context/Vendor/Order/Partials/Shippings/_shipped.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/Partials/Shippings/_shipped.html.twig new file mode 100644 index 0000000..6ab7ca9 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/Partials/Shippings/_shipped.html.twig @@ -0,0 +1,4 @@ + + + {{ 'sylius.ui.shipped'|trans }} + \ No newline at end of file diff --git a/OpenMarketplace/templates/Context/Vendor/Order/Partials/_address.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_address.html.twig new file mode 100644 index 0000000..4d2a2d4 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_address.html.twig @@ -0,0 +1,16 @@ +{% import "@SyliusUi/Macro/flags.html.twig" as flags %} + +
+ {{ address.firstName }} {{ address.lastName }} + {% if address.company %} + {{ address.company }}
+ {% endif %} + {{ address.phoneNumber }}
+ {{ address.street }}
+ {{ address.city }}
+ {% if address|sylius_province_name is not empty %} + {{ address|sylius_province_name }}
+ {% endif %} + {{ flags.fromCountryCode(address.countryCode) }} + {{ address.countryCode|sylius_country_name|upper }} {{ address.postcode }} +
\ No newline at end of file diff --git a/OpenMarketplace/templates/Context/Vendor/Order/Partials/_addresses.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_addresses.html.twig new file mode 100644 index 0000000..8b0f3d2 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_addresses.html.twig @@ -0,0 +1,16 @@ +{% if order.billingAddress is not null %} +

+ {{ 'sylius.ui.billing_address'|trans }} +

+
+ {% include 'Context/Vendor/Order/Partials/_address.html.twig' with {'address': order.billingAddress} %} +
+{% endif %} +{% if order.shippingAddress is not null %} +

+ {{ 'sylius.ui.shipping_address'|trans }} +

+
+ {% include 'Context/Vendor/Order/Partials/_address.html.twig' with {'address': order.shippingAddress} %} +
+{% endif %} \ No newline at end of file diff --git a/OpenMarketplace/templates/Context/Vendor/Order/Partials/_customerInfo.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_customerInfo.html.twig new file mode 100644 index 0000000..378a287 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_customerInfo.html.twig @@ -0,0 +1,32 @@ +
+ + + {% if customer.phoneNumber is not empty %} +
+ + + {{ customer.phoneNumber }} + +
+ {% endif %} + {% if order.customerIp is defined and order.customerIp is not empty %} +
+ + + {{ order.customerIp }} + +
+ {% endif %} +
diff --git a/OpenMarketplace/templates/Context/Vendor/Order/Partials/_item.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_item.html.twig new file mode 100644 index 0000000..2e24d6d --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_item.html.twig @@ -0,0 +1,50 @@ +{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} + +{% set orderPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT') %} +{% set unitPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_UNIT_PROMOTION_ADJUSTMENT') %} +{% set shippingAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::SHIPPING_ADJUSTMENT') %} +{% set taxAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::TAX_ADJUSTMENT') %} + +{% set variant = item.variant %} +{% set product = variant.product %} + +{% set aggregatedUnitPromotionAdjustments = item.getAdjustmentsTotalRecursively(unitPromotionAdjustment) + item.getAdjustmentsTotalRecursively(orderPromotionAdjustment) %} +{% set subtotal = (item.unitPrice * item.quantity) + aggregatedUnitPromotionAdjustments %} + +{% set taxIncluded = sylius_admin_order_unit_tax_included(item) %} +{% set taxExcluded = sylius_admin_order_unit_tax_excluded(item) %} + + + + {% include '@SyliusAdmin/Product/_info.html.twig' %} + + + {{ money.format(item.unitPrice, order.currencyCode) }} + + + {{ money.format(item.units.first.adjustmentsTotal(unitPromotionAdjustment), order.currencyCode) }} + + + ~ {{ money.format(item.units.first.adjustmentsTotal(orderPromotionAdjustment), order.currencyCode) }} + + + {{ money.format(item.fullDiscountedUnitPrice, order.currencyCode) }} + + + {{ item.quantity }} + + + {{ money.format(subtotal, order.currencyCode) }} + + +
{{ money.format(taxExcluded, order.currencyCode) }}
+
+
{{ money.format(taxIncluded, order.currencyCode) }} +
+ ({{ 'sylius.ui.included_in_price'|trans }}) +
+ + + {{ money.format(item.total, order.currencyCode) }} + + diff --git a/OpenMarketplace/templates/Context/Vendor/Order/Partials/_orderDetails.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_orderDetails.html.twig new file mode 100644 index 0000000..6e866ea --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_orderDetails.html.twig @@ -0,0 +1,22 @@ +
+
+
+ {% include 'Context/Vendor/Order/Partials/_payments.html.twig' %} +
+
+ {% include 'Context/Vendor/Order/Partials/_shipments.html.twig' %} +
+
+
+
+ {% set customer = order.customer %} + {% include 'Context/Vendor/Order/Partials/_customerInfo.html.twig' %} +
+
+ {% include 'Context/Vendor/Order/Partials/_addresses.html.twig' %} +
+
+ {% include 'Context/Vendor/Order/Partials/_resendEmail.html.twig' %} +
+
+
\ No newline at end of file diff --git a/OpenMarketplace/templates/Context/Vendor/Order/Partials/_orderTable.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_orderTable.html.twig new file mode 100644 index 0000000..da1b037 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_orderTable.html.twig @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + {% for item in order.items %} + {% include 'Context/Vendor/Order/Partials/_item.html.twig' %} + {% endfor %} + + + {% include 'Context/Vendor/Order/Partials/_totals.html.twig' %} + +
{{ 'sylius.ui.order_item_product'|trans }}{{ 'sylius.ui.unit_price'|trans }}{{ 'sylius.ui.unit_discount'|trans }}{{ 'sylius.ui.distributed_order_discount'|trans }}{{ 'sylius.ui.discounted_unit_price'|trans }}{{ 'sylius.ui.quantity'|trans }}{{ 'sylius.ui.subtotal'|trans }}{{ 'sylius.ui.tax'|trans }}{{ 'sylius.ui.total'|trans }}
\ No newline at end of file diff --git a/OpenMarketplace/templates/Context/Vendor/Order/Partials/_orderTitle.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_orderTitle.html.twig new file mode 100644 index 0000000..2f8a92b --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_orderTitle.html.twig @@ -0,0 +1,29 @@ +
+
+
+

+ +
+ {{ 'sylius.ui.order'|trans }} #{{ order.number }} +
+
+
+ {{ order.checkoutCompletedAt|format_datetime }} +
+
+ {% include [('@SyliusAdmin/Order/Label/State' ~ '/' ~ order.state ~ '.html.twig'), '@SyliusUi/Label/_default.html.twig'] with {'value': ('sylius.ui.' ~ order.state)|trans} %} +
+
+ {{ order.currencyCode }} +
+ +
+
+
+

+
+
+ {% set menu = knp_menu_get('sylius.vendor.order.show', [], {'order': order}) %} + {{ knp_menu_render(menu, {'template': '@SyliusUi/Menu/top.html.twig'}) }} +
+
diff --git a/OpenMarketplace/templates/Context/Vendor/Order/Partials/_payments.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_payments.html.twig new file mode 100644 index 0000000..42a2ec3 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_payments.html.twig @@ -0,0 +1,30 @@ +{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} +{% if order.hasPayments %} +
+ {% include '@SyliusAdmin/Order/Label/PaymentState/' ~ order.paymentState ~ '.html.twig' with { 'value': 'sylius.ui.' ~ order.paymentState, 'attached': true } %} +

{{ 'sylius.ui.payments'|trans }}

+
+ {% for payment in order.payments %} +
+
+ {% include '@SyliusAdmin/Common/Label/paymentState.html.twig' with {'data': payment.state} %} +
+
+
+ {{ payment.method }} +
+
+ {{ money.format(payment.amount, payment.order.currencyCode) }} +
+
+
+ {% endfor %} +
+
+{% else %} +
+ + {{ 'sylius.ui.no_payments'|trans }} + +
+{% endif %} diff --git a/OpenMarketplace/templates/Context/Vendor/Order/Partials/_resendEmail.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_resendEmail.html.twig new file mode 100644 index 0000000..a781e1e --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_resendEmail.html.twig @@ -0,0 +1,6 @@ +
+ {% set path = path('open_marketplace_vendor_orders_resend_confirmation_email', {'id': order.id, '_csrf_token': csrf_token(order.id)}) %} + + {{ 'sylius.ui.resend_the_order_confirmation_email'|trans }} + +
diff --git a/OpenMarketplace/templates/Context/Vendor/Order/Partials/_shipments.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_shipments.html.twig new file mode 100644 index 0000000..f9f9432 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_shipments.html.twig @@ -0,0 +1,47 @@ +{% set shippingStates = { + 'ready': 'Context/Vendor/Order/Partials/Shippings/_ready.html.twig', + 'partially_shipped': 'Context/Vendor/Order/Partials/Shippings/_partiallyShipped.html.twig', + 'shipped': 'Context/Vendor/Order/Partials/Shippings/_shipped.html.twig', + 'cancelled': 'Context/Vendor/Order/Partials/Shippings/_cancelled.html.twig' +} %} + +
+ {% include shippingStates[order.shippingState] %} + + {% if order.hasShipments %} +

{{ 'sylius.ui.shipments'|trans }}

+
+ {% for shipment in order.shipments %} +
+
+ {% include '@SyliusAdmin/Common/Label/shipmentState.html.twig' with {'data': shipment.state} %} +
+ + +
+
+ {{ shipment.method }} +
+
+ {{ shipment.method.zone }} +
+ {% if shipment.shippedAt is not empty %} + {{ 'sylius.ui.shipped_at'|trans }}: {{ shipment.shippedAt|date('d-m-Y H:i:s') }} + {% endif %} +
+ + {% if shipment.tracking is not empty %} +
+ {{ 'sylius.ui.tracking_code'|trans|upper }} +

{{ shipment.tracking }}

+
+ {% endif %} + + {% if sm_can(shipment, 'ship', 'sylius_shipment') %} + {% include 'Context/Vendor/Order/Partials/Shippings/_shipmentsForm.html.twig' %} + {% endif %} +
+ {% endfor %} +
+ {% endif %} +
\ No newline at end of file diff --git a/OpenMarketplace/templates/Context/Vendor/Order/Partials/_totals.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_totals.html.twig new file mode 100644 index 0000000..ed0506d --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_totals.html.twig @@ -0,0 +1,96 @@ +{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} + +{% set orderShippingPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_SHIPPING_PROMOTION_ADJUSTMENT') %} +{% set shippingAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::SHIPPING_ADJUSTMENT') %} +{% set taxAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::TAX_ADJUSTMENT') %} + +{% set orderShippingPromotions = sylius_aggregate_adjustments(order.getAdjustmentsRecursively(orderShippingPromotionAdjustment)) %} + + + + + {{ 'sylius.ui.tax_total'|trans }}: + {{ money.format(order.taxTotal, order.currencyCode) }} + + + {{ 'sylius.ui.items_total'|trans }}: + {{ money.format(order.itemsTotal, order.currencyCode) }} + + + + + +

{{ 'open_marketplace.ui.commission'|trans }} ({{ 'sylius.ui.included_in_price'|trans }})

+ + + {{ 'open_marketplace.ui.commission'|trans }}: + {{ money.format(order.commissionTotal, order.currencyCode) }} + + + + + + {% if not order.adjustments(shippingAdjustment).isEmpty() %} +
+
{{ 'sylius.ui.shipping'|trans }}:
+ {% for shipment in order.shipments %} + {% for adjustment in shipment.adjustments(shippingAdjustment) %} +
+
{{ money.format(adjustment.amount, order.currencyCode) }}
+
+
+ {{ adjustment.label }}: +
+
+
+ {% endfor %} + + {% for adjustment in shipment.adjustments(taxAdjustment) %} +
+
+ {{ money.format(adjustment.amount, order.currencyCode) }} + {% if adjustment.isNeutral %} + ({{ 'sylius.ui.included_in_price'|trans }}) + {% endif %} +
+
+
+ {{ adjustment.label }}: +
+
+
+ {% endfor %} + {% endfor %} +
+ {% else %} +

{{ 'sylius.ui.no_shipping_charges'|trans }}

+ {% endif %} + + {% if not orderShippingPromotions is empty %} + +
+
{{ 'sylius.ui.shipping_discount'|trans }}:
+ {% for label, amount in orderShippingPromotions %} +
+
+ {{ money.format(amount, order.currencyCode) }} +
+
+ {% endfor %} +
+ + {% endif %} + + {{ 'sylius.ui.shipping_total'|trans }}: + {{ money.format(order.shippingTotal, order.currencyCode) }} + + + +{% include 'Context/Vendor/Order/Partials/_totalsPromotions.html.twig' %} + + + + {{ 'sylius.ui.order_total'|trans }}: + {{ money.format(order.total, order.currencyCode) }} + + diff --git a/OpenMarketplace/templates/Context/Vendor/Order/Partials/_totalsPromotions.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_totalsPromotions.html.twig new file mode 100644 index 0000000..4d5ecd6 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/Partials/_totalsPromotions.html.twig @@ -0,0 +1,31 @@ +{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} + +{% set orderPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT') %} +{% set unitPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_UNIT_PROMOTION_ADJUSTMENT') %} + + + + {% set orderPromotionAdjustments = sylius_aggregate_adjustments(order.getAdjustmentsRecursively(orderPromotionAdjustment)) %} + {% set unitPromotionAdjustments = sylius_aggregate_adjustments(order.getAdjustmentsRecursively(unitPromotionAdjustment)) %} + {% set promotionAdjustments = orderPromotionAdjustments|merge(unitPromotionAdjustments) %} + {% if not promotionAdjustments is empty %} +
+
{{ 'sylius.ui.promotions'|trans }}:
+ {% for label, amount in promotionAdjustments %} +
+
{{ money.format(amount, order.currencyCode) }}
+
{{ label }}:
+
+ {% endfor %} +
+ {% else %} +

{{ 'sylius.ui.no_promotion'|trans }}.

+ {% endif %} + + + {% set orderPromotionTotal = order.getAdjustmentsTotalRecursively(orderPromotionAdjustment) %} + {% set unitPromotionTotal = order.getAdjustmentsTotalRecursively(unitPromotionAdjustment) %} + {{ 'sylius.ui.promotion_total'|trans }}: + {{ money.format(orderPromotionTotal + unitPromotionTotal, order.currencyCode) }} + + diff --git a/OpenMarketplace/templates/Context/Vendor/Order/index.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/index.html.twig new file mode 100644 index 0000000..6344da9 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/index.html.twig @@ -0,0 +1,18 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% block title %}{{ 'sylius.ui.order_history'|trans }} | {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} +
{{ 'sylius.ui.order_history'|trans }}
+{% endblock %} + +{% block subcontent %} + {% include "Context/Vendor/_header.html.twig" with { + "header": 'open_marketplace.ui.orders', + "subheader": 'open_marketplace.ui.manage_orders', + "icon": 'suitcase' + } %} + + {{ sylius_grid_render(resources, '@SyliusShop/Grid/_default.html.twig') }} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/Order/show.html.twig b/OpenMarketplace/templates/Context/Vendor/Order/show.html.twig new file mode 100644 index 0000000..bfa563b --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Order/show.html.twig @@ -0,0 +1,19 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% block title %}{{ 'sylius.ui.order_history'|trans }} | {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} + {{ 'sylius.ui.order_history'|trans }} +
/
+
{{ resource.id }}
+
/
+
{{ 'sylius.ui.show'|trans }}
+{% endblock %} + +{% block subcontent %} + {% include 'Context/Vendor/Order/Partials/_orderTitle.html.twig' %} + {% include 'Context/Vendor/Order/Partials/_orderTable.html.twig' %} + {% include 'Context/Vendor/Order/Partials/_orderDetails.html.twig' %} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/ProductListing/_form.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductListing/_form.html.twig new file mode 100644 index 0000000..b87fc20 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductListing/_form.html.twig @@ -0,0 +1,145 @@ +{% block subcontent %} + {% set header = 'open_marketplace.ui.create_product_listing' %} + {% if editMode == true %} + {% set header = 'open_marketplace.ui.edit_product_listing' %} + {% endif %} + + {% include "Context/Vendor/_header.html.twig" with { + "header": header, + "icon": 'edit' + } %} + + {{ form_start(form, { 'attr': {'class': 'ui form dirtylisten'}}) }} + {% include '@SyliusAdmin/Crud/form_validation_errors_checker.html.twig' %} +
+
+
+ {{ form_errors(form) }} +
+
+
+

{{ 'sylius.ui.details'|trans }}

+
+
+ {{ form_row(form.code) }} +
+
+
+ {{ form_row(form.channels) }} +
+

{{ 'sylius.ui.pricing'|trans }}

+
+
+
+ {% for channel, prices in form.productListingPrices %} +
+
+ + {{ prices.vars.name }} +
+
+
+ {{ 'sylius.ui.product.product_not_active_in_channel'|trans }} +
+ {% for price in prices %} +
+ {{ form_label(price) }} +
+ {{ form_widget(price) }} + {{ form_errors(price) }} +
+
+ {% endfor %} +
+
+ {% endfor %} +
+
+
+ {{ form_row(form.taxCategory) }} +
+
+
+
+
+
+

{{ 'sylius.ui.shipping'|trans }}

+
+
+ {{ form_row(form.shippingRequired) }} + {{ form_row(form.shippingCategory) }} +
+
+
+
+

{{ 'sylius.ui.translations'|trans }}

+
+
+
+ {% for index, translations in form.translations %} + {% set flag = translations.vars.name|split('_')[1]|default(translations.vars.name)|lower %} +
+
+ + + {{ translations.vars.name }} +
+
+ {% for translation in translations %} + {{ form_label(translation) }} + {{ form_widget(translation) }} + {{ form_errors(translation) }} + {% endfor %} +
+
+ {% endfor %} +
+
+
+
+
+ {% form_theme form '@SyliusAdmin/Product/Attribute/attributesCollection.html.twig' %} +
+
+

{{ 'sylius.ui.attributes'|trans }}

+
+
+ {{ render(url('open_marketplace_vendor_attributes_listing')) }} +
+ {{ form_widget(form.attributes, {'attr': {'translations': form.translations} }) }} +
+
+
+ {% include 'Context/Vendor/ProductListing/form/_images.html.twig' %} +
+

{{ 'sylius.ui.taxonomy'|trans }}

+ +
+ {{ form_row(form.mainTaxon, { + 'remote_url': path('open_marketplace_vendor_taxonomy_ajax_taxon_by_name_phrase'), + 'load_edit_url': path('open_marketplace_vendor_taxonomy_ajax_taxon_by_code') + }) }} + +
+

{{ 'sylius.ui.product_taxon'|trans }}:

+
+ {{ form_widget(form.productDraftTaxons) }} + +
+
+
+
+
+
+
+
+
+ {{ form_row(form._token) }} + {{ form_widget(form.save) }} +
+
+ {{ form_end(form, {'render_rest': true}) }} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/ProductListing/_menu.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductListing/_menu.html.twig new file mode 100644 index 0000000..ecf1bcf --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductListing/_menu.html.twig @@ -0,0 +1,9 @@ +
+
+ {% if definition.actionGroups.main is defined %} + {% for action in definition.getEnabledActions('main') %} + {{ sylius_grid_render_action(grid, action, null) }} + {% endfor %} + {% endif %} +
+
diff --git a/OpenMarketplace/templates/Context/Vendor/ProductListing/_productListings.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductListing/_productListings.html.twig new file mode 100644 index 0000000..839a1ad --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductListing/_productListings.html.twig @@ -0,0 +1,77 @@ +{% import '@SyliusUi/Macro/pagination.html.twig' as pagination %} +{% import '@SyliusUi/Macro/buttons.html.twig' as buttons %} +{% import '@SyliusUi/Macro/messages.html.twig' as messages %} +{% import '@SyliusUi/Macro/table.html.twig' as table %} + +{% set definition = grid.definition %} +{% set data = grid.data %} + +{% set path = path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) %} +{% set criteria = app.request.query.get('criteria') %} + +{% if definition.enabledFilters|length > 0 %} + +
+
+ + + {{ 'sylius.ui.filters'|trans }} +
+
+
+
+ {% for filter in definition.enabledFilters|filter(filter => filter.enabled)|sort_by('position') %} +
+ {{ sylius_grid_render_filter(grid, filter) }} +
+ {% endfor %} +
+ {{ buttons.filter() }} + {{ buttons.resetFilters(path) }} +
+
+
+{% endif %} + + +
+
+ {% if data|length > 0 and definition.actionGroups.bulk is defined and definition.getEnabledActions('bulk')|length > 0 %} +
+ {% for action in definition.getEnabledActions('bulk') %} + {{ sylius_grid_render_bulk_action(grid, action, null) }} + {% endfor %} +
+ {% endif %} +
+ {{ pagination.simple(data) }} +
+ {% if definition.limits|length > 1 and data|length > min(definition.limits) %} +
+ +
+ {% endif %} +
+ + {% if data|length > 0 %} +
+ + + + {{ table.headers(grid, definition, app.request.attributes) }} + + + + {% for row in data %} + {{ table.row(grid, definition, row) }} + {% endfor %} + +
+
+ {% else %} + {{ messages.info('sylius.ui.no_results_to_display') }} + {% endif %} + {{ pagination.simple(data) }} +
diff --git a/OpenMarketplace/templates/Context/Vendor/ProductListing/create.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductListing/create.html.twig new file mode 100644 index 0000000..bf75335 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductListing/create.html.twig @@ -0,0 +1,35 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} + +{% set header = configuration.vars.header|default(metadata.applicationName~'.ui.new_'~metadata.name) %} +{% set event_prefix = metadata.applicationName ~ '.vendor.' ~ metadata.name ~ '.create' %} + +{% block title %}{{ header|trans }} {{ parent() }}{% endblock %} + +{% form_theme form '@SyliusAdmin/Form/theme.html.twig' %} + +{% block breadcrumb %} + +{% endblock %} + +{% block subcontent %} + {{ include('Context/Vendor/ProductListing/_form.html.twig', {"editMode": false}) }} +{% endblock %} + +{% block stylesheets %} + {{ parent() }} + {{ sylius_template_event([event_prefix ~ '.stylesheets', 'sylius.admin.create.stylesheets'], { 'metadata': metadata }) }} +{% endblock %} + +{% block javascripts %} + {{ encore_entry_script_tags('admin-entry', null, 'admin') }} +{% endblock %} + + diff --git a/OpenMarketplace/templates/Context/Vendor/ProductListing/details.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductListing/details.html.twig new file mode 100644 index 0000000..48cfe9c --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductListing/details.html.twig @@ -0,0 +1,82 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% block title %}{{ 'sylius.ui.my_account'|trans }} | {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} + {{ 'open_marketplace.ui.product_list'|trans }} +
/
+
{{ 'sylius.ui.show'|trans }}
+{% endblock %} + +{% set productDraft = product_draft %} + +{% block subcontent %} + {% include "Context/Vendor/_header.html.twig" with { + "header": 'open_marketplace.ui.show_product_listing', + "icon": 'file', + } %} + + {% set productDraft = product_draft%} + +

{{ 'sylius.ui.details'|trans }}

+
+ + + + + + + + + + + + + + + + + + + +
{{ 'open_marketplace.ui.code'|trans }} + {{ productDraft.code }} +
{{ 'open_marketplace.ui.published_at'|trans }} + {{ productDraft.publishedAt | date }} +
{{ 'open_marketplace.ui.status'|trans }} + {{ productDraft.status }} +
{{ 'open_marketplace.ui.status'|trans }} + {% if productDraft.status == 'rejected' %} + {{ 'open_marketplace.ui.rejected'|trans }} + {% elseif productDraft.status == 'under_verification' %} + {{ 'open_marketplace.ui.under_verification'|trans }} + {% elseif productDraft.status == 'verified' %} + {{ 'open_marketplace.ui.verified'|trans }} + {% else %} + {{ 'open_marketplace.ui.created'|trans }} + {% endif %} +
+
+ + + {% include 'Context/Common/ProductListing/_pricing.html.twig' with { taxCategory: true } %} + + {% include 'Context/Vendor/ProductListing/details/_shipping.html.twig' %} + + {% include 'Context/Vendor/ProductListing/details/_taxons.html.twig' %} + + {% include 'Context/Vendor/ProductListing/details/_moreDetails.html.twig' %} + + {% include 'Context/Vendor/ProductListing/details/_attributes.html.twig' %} + + {% include 'Context/Vendor/ProductListing/details/_media.html.twig' %} + +{% endblock %} + +{% set event_prefix = metadata.applicationName ~ '.vendor.' ~ metadata.name ~ '.create' %} +{% block stylesheets %} + {{ parent() }} + + {{ sylius_template_event([event_prefix ~ '.stylesheets', 'sylius.admin.create.stylesheets'], { 'metadata': metadata }) }} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/ProductListing/details/_attributes.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductListing/details/_attributes.html.twig new file mode 100644 index 0000000..4be934e --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductListing/details/_attributes.html.twig @@ -0,0 +1,49 @@ +{% import '@SyliusUi/Macro/flags.html.twig' as flags %} +
+

{{ 'sylius.ui.attributes'|trans }}

+
+ {% if productDraft.attributes|length == 0 %} + {{ 'open_marketplace.ui.no_draft_attributes'|trans }} + {% else %} + + {% for locale in setLocales %} + {% set data_tab = (locale is not null ? locale|sylius_locale_name : 'non-translatable') %} +
+ + + {% for attributeValue in productDraft.attributes|filter(attributeValue => attributeValue.localeCode == locale) %} + + + + + {% endfor %} + +
+ {{ attributeValue.name }} + + {% include [ + '@SyliusAdmin/Product/Show/Types/' ~ attributeValue.type ~ '.html.twig', + '@SyliusAttribute/Types/' ~ attributeValue.type ~ '.html.twig', + '@SyliusAdmin/Product/Show/Types/default.html.twig' + ] with { + 'attribute': attributeValue + } %} +
+
+ {% endfor %} + {% endif %} +
+
diff --git a/OpenMarketplace/templates/Context/Vendor/ProductListing/details/_media.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductListing/details/_media.html.twig new file mode 100644 index 0000000..a82ccce --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductListing/details/_media.html.twig @@ -0,0 +1,27 @@ +{% if productDraft.images|length == 0 %} +
+

{{ 'sylius.ui.media'|trans }}

+
+ {{ 'open_marketplace.ui.no_media_uploaded'|trans }} +
+
+{% else %} +
+
+ + {{ 'sylius.ui.media'|trans }} +
+
+
+ {% for image in productDraft.images %} + {% set path = image.path is not null ? image.path|imagine_filter('sylius_admin_product_small_thumbnail') : asset('assets/admin/img/200x200.png') %} +
+ + + +
+ {% endfor %} +
+
+
+{% endif %} diff --git a/OpenMarketplace/templates/Context/Vendor/ProductListing/details/_moreDetails.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductListing/details/_moreDetails.html.twig new file mode 100644 index 0000000..5bc8c57 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductListing/details/_moreDetails.html.twig @@ -0,0 +1,42 @@ +

{{ 'sylius.ui.translations'|trans }}

+
+
+ {% for translation in productDraft.translations %} +
+ + + {{ translation.locale|sylius_locale_name }} +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ 'sylius.ui.name'|trans }}{{ translation.name }}
{{ 'sylius.ui.slug'|trans }}{{ translation.slug }}
{{ 'sylius.ui.description'|trans }}{{ translation.description|nl2br }}
{{ 'sylius.ui.meta_keywords'|trans }}{{ translation.metaKeywords }}
{{ 'sylius.ui.meta_description'|trans }}{{ translation.metaDescription }}
{{ 'sylius.ui.short_description'|trans }}{{ translation.shortDescription }}
+
+ {% endfor %} +
+
diff --git a/OpenMarketplace/templates/Context/Vendor/ProductListing/details/_shipping.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductListing/details/_shipping.html.twig new file mode 100644 index 0000000..93fe8eb --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductListing/details/_shipping.html.twig @@ -0,0 +1,31 @@ +{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} + +
+

{{ 'open_marketplace.ui.shipping_details'|trans }}

+
+ + + + + + + + + + + +
{{ 'open_marketplace.ui.is_shipping_required'|trans }} + {% if productDraft.shippingRequired %} + {{ 'open_marketplace.ui.yes'|trans }} + {% else %} + {{ 'open_marketplace.ui.no'|trans }} + {% endif %} +
{{ 'open_marketplace.ui.shipping_category'|trans }} + {% if productDraft.shippingCategory %} + {{ productDraft.shippingCategory.name }} + {% else %} + {{ 'open_marketplace.ui.none'|trans }} + {% endif %} +
+
+
diff --git a/OpenMarketplace/templates/Context/Vendor/ProductListing/details/_taxons.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductListing/details/_taxons.html.twig new file mode 100644 index 0000000..a992dad --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductListing/details/_taxons.html.twig @@ -0,0 +1,29 @@ +
+

{{ 'sylius.ui.taxonomy'|trans }}

+
+ {% if productDraft.mainTaxon == null and productDraft.productDraftTaxons|length == 0 %} + {{ 'open_marketplace.ui.no_draft_taxons'|trans }} + {% else %} + + + {% if productDraft.mainTaxon != null %} + + + + + {% endif %} + + + + + +
{{ 'sylius.ui.main_taxon'|trans }}{{ productDraft.mainTaxon.getFullName }}
{{ 'sylius.ui.product_taxons'|trans }} +
    + {% for productDraftTaxon in productDraft.productDraftTaxons %} +
  • {{ productDraftTaxon.getTaxon.getFullName }}
  • + {% endfor %} +
+
+ {% endif %} +
+
diff --git a/OpenMarketplace/templates/Context/Vendor/ProductListing/form/_attributeChoice.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductListing/form/_attributeChoice.html.twig new file mode 100644 index 0000000..33416ae --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductListing/form/_attributeChoice.html.twig @@ -0,0 +1,6 @@ +
+ {{ form_widget(form, {'attr': {'class': 'ui fluid search dropdown', 'id': 'sylius_product_attribute_choice'}}) }} + +
diff --git a/OpenMarketplace/templates/Context/Vendor/ProductListing/form/_images.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductListing/form/_images.html.twig new file mode 100644 index 0000000..3119103 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductListing/form/_images.html.twig @@ -0,0 +1,10 @@ +{% form_theme form 'Context/Vendor/ProductListing/form/theme/image_theme.html.twig' %} + +
+
+

{{ 'sylius.ui.media'|trans }}

+
+
+
{{ form_row(form.images, {'label': false}) }}
+
+
diff --git a/OpenMarketplace/templates/Context/Vendor/ProductListing/form/attributeValues.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductListing/form/attributeValues.html.twig new file mode 100644 index 0000000..2f07c49 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductListing/form/attributeValues.html.twig @@ -0,0 +1,83 @@ +{% import _self as self %} +{% import '@SyliusUi/Macro/flags.html.twig' as flags %} + +{% set subject = 'product' %} + +{% for code, localeCodes in forms %} +
+
+ {{ (localeCodes|first).vars.label }} +
+ +
+
+
+ {% for localeCode, form in localeCodes %} +
+ {% set id = form.vars.label|replace({' ': '_'})|lower %} +
+
+ +
+
+ {% if 'type_checkbox' in form.vars.cache_key %} +
+ {{ self.formField(form, count, id, '', subject, 'sylius') }} + +
+ {% else %} + {{ self.formField(form, count, id, '', subject, 'sylius') }} + {% endif %} +
+
+ {% if localeCode %} + {{ 'sylius.ui.apply_to_all'|trans }} + {% endif %} +
+
+ + + {% set count = count + 1 %} +
+ {% endfor %} +
+
+{% endfor %} + +{% macro formField(item, count, id, prefix, subject, applicationName) %} + {% from _self import formField %} + {% if item.children|length > 0 %} + {% set prefix = prefix ~ '_' ~ item.vars.name %} + {% for child in item.children %} + {{ formField(child, count, id, prefix, subject, applicationName) }} + {% endfor %} + {% elseif item.vars.name != '_token' %} + {% set namePrefix = prefix|replace({'_': ']['}) %} + {% set dataName = applicationName ~ '_' ~ subject ~ '[attributes][' ~ count~namePrefix ~ '][' ~ item.vars.name ~ ']' %} + {% if item.vars.multiple is defined and item.vars.multiple %} + {% set dataName = dataName ~ '[]' %} + {% endif %} + + {{ form_widget(item, {'id': id, 'attr': {'data-name': dataName }}) }} + {% endif %} +{% endmacro %} + diff --git a/OpenMarketplace/templates/Context/Vendor/ProductListing/form/theme/form_theme.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductListing/form/theme/form_theme.html.twig new file mode 100644 index 0000000..73a2d11 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductListing/form/theme/form_theme.html.twig @@ -0,0 +1,130 @@ +{% extends '@SyliusUi/Form/theme.html.twig' %} + +{% block collection_widget -%} + {% from '@SyliusResource/Macros/notification.html.twig' import error %} + {% import _self as self %} + {% set attr = attr|merge({'class': attr.class|default ~ ' controls collection-widget'}) %} + + {% apply spaceless %} +
+ {{ error(form.vars.errors) }} + + {% if prototypes|default is iterable %} + {% for key, subPrototype in prototypes %} + + {% endfor %} + {% endif %} + +
+ {% for child in form %} + {{ self.collection_item(child, allow_delete, button_delete_label, loop.index0) }} + {% endfor %} +
+ + {% if prototype is defined and allow_add %} + + + {{ button_add_label|trans }} + + {% endif %} +
+ {% endapply %} +{%- endblock collection_widget %} + +{% macro collection_item(form, allow_delete, button_delete_label, index) %} + {% apply spaceless %} +
+
+ {{ form_widget(form) }} +
+ {% if allow_delete %} + + + {{ button_delete_label|trans }} + + {% endif %} +
+ {% endapply %} +{% endmacro %} + +{% block sylius_product_image_widget %} + {% apply spaceless %} + {{ form_row(form.type) }} + + {% if form.vars.value.path|default(null) is not null %} + {{ form.vars.value.type }} + {% endif %} + +
+ {{- form_errors(form.file) -}} +
+{# {% if product.id is not null and 0 != product.variants|length and not product.simple %}#} +{# {{ form_row(form.productVariants) }}#} +{# {% endif %}#} + {% endapply %} +{% endblock %} + +{% block sylius_taxon_image_widget %} + {% apply spaceless %} + {{ form_row(form.type) }} + {% if form.vars.value.path|default(null) is null %} + + {% else %} + {{ form.vars.value.type }} + + {% endif %} + +
+ {{- form_errors(form.file) -}} +
+ {% endapply %} +{% endblock %} + +{% block sylius_avatar_image_widget %} + {% apply spaceless %} + {% if form.vars.value.path|default(null) is not null %} + {{ form.vars.value.type }} + {% endif %} + +
+ +
+
+ {{- form_errors(form.file) -}} +
+ {% endapply %} +{% endblock %} + +{% block sylius_image_widget %} + {% apply spaceless %} + {{ form_row(form.type) }} + + {% if form.vars.value.path|default(null) is not null %} + {{ form.vars.value.type }} + {% endif %} + +
+ {{- form_errors(form.file) -}} +
+ {% endapply %} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/ProductListing/form/theme/image_theme.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductListing/form/theme/image_theme.html.twig new file mode 100644 index 0000000..c58e6da --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductListing/form/theme/image_theme.html.twig @@ -0,0 +1,5 @@ +{% extends 'Context/Vendor/ProductListing/form/theme/form_theme.html.twig' %} + +{% block sylius_product_image_widget %} + {{ block('sylius_image_widget') }} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/ProductListing/index.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductListing/index.html.twig new file mode 100644 index 0000000..397dbf4 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductListing/index.html.twig @@ -0,0 +1,23 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% block title %}{{ 'open_marketplace.ui.product_list'|trans }} | {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} +
{{ 'open_marketplace.ui.product_list'|trans }}
+{% endblock %} + +{% block subcontent %} + {% include "Context/Vendor/_header.html.twig" with { + "header": 'open_marketplace.ui.product_listings', + "subheader": 'open_marketplace.ui.manage_products', + "icon": 'list', + "buttons": "Context/Vendor/ProductListing/_menu.html.twig", + "buttonsData": { + "definition": resources.definition, + "data": resources.data, + "grid": resources, + }, + } %} + {{ sylius_grid_render(resources, 'Context/Vendor/ProductListing/_productListings.html.twig') }} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/ProductListing/update.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductListing/update.html.twig new file mode 100644 index 0000000..623f4af --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductListing/update.html.twig @@ -0,0 +1,31 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% set header = configuration.vars.header|default(metadata.applicationName~'.ui.edit_'~metadata.name) %} +{% set event_prefix = metadata.applicationName ~ '.vendor.' ~ metadata.name ~ '.create' %} + +{% block title %}{{ header|trans }} {{ parent() }}{% endblock %} + +{% form_theme form '@SyliusAdmin/Form/theme.html.twig' %} + +{% block breadcrumb_page %} + {{ 'open_marketplace.ui.product_list'|trans }} +
/
+
{{ 'sylius.ui.edit'|trans }}
+{% endblock %} + +{% block subcontent %} + {{ include('Context/Vendor/ProductListing/_form.html.twig', {"editMode": true}) }} +{% endblock %} + +{% block stylesheets %} + {{ parent() }} + + {{ sylius_template_event([event_prefix ~ '.stylesheets', 'sylius.admin.create.stylesheets'], { 'metadata': metadata }) }} +{% endblock %} + +{% block javascripts %} + {{ encore_entry_script_tags('admin-entry', null, 'admin') }} +{% endblock %} + + diff --git a/OpenMarketplace/templates/Context/Vendor/ProductReviews/_author.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductReviews/_author.html.twig new file mode 100644 index 0000000..b34cc71 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductReviews/_author.html.twig @@ -0,0 +1,28 @@ +{% set author = product_review.author %} + +
+
+ {% if is_vendor_client(product_review.reviewSubject.vendor, author) is same as true %} + {{ author.fullName }} + {% else %} +
{{ author.fullName }}
+ {% endif %} +
+ {{ 'sylius.ui.customer_since'|trans }} {{ author.createdAt|format_date }}. +
+
+ + {% if author.phoneNumber is not empty %} +
+ + + {{ author.phoneNumber }} + +
+ {% endif %} +
diff --git a/OpenMarketplace/templates/Context/Vendor/ProductReviews/_product.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductReviews/_product.html.twig new file mode 100644 index 0000000..1a1be44 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductReviews/_product.html.twig @@ -0,0 +1,8 @@ +{% set product = product_review.reviewSubject %} + +

+ {{ 'sylius.ui.product'|trans }} +

+ diff --git a/OpenMarketplace/templates/Context/Vendor/ProductReviews/index.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductReviews/index.html.twig new file mode 100644 index 0000000..456deaa --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductReviews/index.html.twig @@ -0,0 +1,18 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% block title %}{{ 'sylius.ui.product_reviews'|trans }} | {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} +
{{ 'sylius.ui.product_reviews'|trans }}
+{% endblock %} + +{% block subcontent %} + {% include "Context/Vendor/_header.html.twig" with { + "header": 'open_marketplace.ui.product_reviews', + "subheader": 'open_marketplace.ui.manage_product_reviews', + "icon": 'star' + } %} + + {{ sylius_grid_render(resources, '@SyliusAdmin/Grid/_default.html.twig') }} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/ProductReviews/update.html.twig b/OpenMarketplace/templates/Context/Vendor/ProductReviews/update.html.twig new file mode 100644 index 0000000..a0233ec --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ProductReviews/update.html.twig @@ -0,0 +1,44 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% set header = configuration.vars.header|default(metadata.applicationName~'.ui.edit_'~metadata.name) %} + +{% block title %}{{ header|trans }} {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} + {{ 'sylius.ui.product_reviews'|trans }} +
/
+
{{ resource.id }}
+
/
+
{{ 'sylius.ui.edit'|trans }}
+{% endblock %} + +{% form_theme form '@SyliusUi/Form/theme.html.twig' %} + +{% block subcontent %} + {% include "Context/Vendor/_header.html.twig" with { + "header": 'open_marketplace.ui.edit_product_review', + "icon": 'star' + } %} + +
+ {{ form_start(form, { 'attr': {'class': 'ui form'}}) }} +
+
+
+ {{ form_errors(form) }} + {{ form_row(form.title) }} + {{ form_row(form.comment) }} +
+ +
+
+ {% include 'Context/Vendor/ProductReviews/_product.html.twig' %} + {% include 'Context/Vendor/ProductReviews/_author.html.twig' %} +
+
+ {{ form_end(form) }} +
+{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/Profile/_menu.html.twig b/OpenMarketplace/templates/Context/Vendor/Profile/_menu.html.twig new file mode 100644 index 0000000..64aed2d --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Profile/_menu.html.twig @@ -0,0 +1,8 @@ +
+ {% if is_pending_vendor_profile_update() is same as true %} + + + {{ 'sylius.ui.edit'|trans }} + + {% endif %} +
diff --git a/OpenMarketplace/templates/Context/Vendor/Profile/index.html.twig b/OpenMarketplace/templates/Context/Vendor/Profile/index.html.twig new file mode 100644 index 0000000..0ec1a37 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Profile/index.html.twig @@ -0,0 +1,75 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% block title %}{{ 'sylius.ui.my_account'|trans }} | {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} +
{{ 'sylius.ui.profile'|trans }}
+{% endblock %} + +{% block subcontent %} + {% include "Context/Vendor/_header.html.twig" with { + "header": 'open_marketplace.ui.my_vendor_account', + "subheader": 'open_marketplace.ui.manage_your_vendor_information_and_preferences', + "icon": 'user', + "buttons": "Context/Vendor/Profile/_menu.html.twig" + } %} + +
+ + {{ sylius_template_event('sylius.shop.account.dashboard.after_content_header', {'vendor': vendor}) }} + +
+
+ {% if is_pending_vendor_profile_update() == false %} +
+
+ {{ 'sylius.ui.info'|trans }} +
+

+ {{ 'open_marketplace.ui.pending_update_message'|trans }} +

+
+ {% endif %} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ 'open_marketplace.ui.company_name'|trans }}{{ vendor.companyName }}
{{ 'open_marketplace.ui.tax_identifier'|trans }}{{ vendor.taxIdentifier }}
{{ 'open_marketplace.ui.bank_account_number'|trans }}{{ vendor.bankAccountNumber }}
{{ 'open_marketplace.ui.phone_number'|trans }}{{ vendor.phoneNumber }}
{{ 'open_marketplace.ui.country'|trans }}{{ vendor.vendorAddress.country }}
{{ 'open_marketplace.ui.postal_code'|trans }}{{ vendor.vendorAddress.postalCode }}
{{ 'open_marketplace.ui.city'|trans }}{{ vendor.vendorAddress.city }}
{{ 'open_marketplace.ui.street'|trans }}{{ vendor.vendorAddress.street }}
+
+
+
+ {{ sylius_template_event('sylius.shop.account.dashboard.after_information', {'vendor': vendor}) }} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/Profile/update.html.twig b/OpenMarketplace/templates/Context/Vendor/Profile/update.html.twig new file mode 100644 index 0000000..a345608 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Profile/update.html.twig @@ -0,0 +1,55 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% form_theme form '@SyliusShop/Form/theme.html.twig' %} + +{% block title %}{{ 'sylius.ui.your_profile'|trans }} | {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} + {{ 'sylius.ui.profile'|trans }} +
/
+
{{ 'sylius.ui.edit'|trans }}
+{% endblock %} + +{% block subcontent %} + {% include "Context/Vendor/_header.html.twig" with { + "header": 'open_marketplace.ui.your_vendor_profile', + "subheader": 'open_marketplace.ui.edit_your_vendor_information', + "icon": 'user', + } %} + +
+ {{ form_start(form, {'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }} + {{ form_row(form.companyName, sylius_test_form_attribute('companyName')) }} + {{ form_row(form.taxIdentifier) }} + {{ form_row(form.bankAccountNumber) }} + {{ form_row(form.phoneNumber) }} + +
+ {% form_theme form 'Context/Vendor/ProductListing/form/theme/image_theme.html.twig' %} + + {{ form_row(form.image, {'label': false}) }} +
+ +
+ {% form_theme form 'Context/Vendor/ProductListing/form/theme/image_theme.html.twig' %} + + {{ form_row(form.backgroundImage, {'label': false}) }} +
+ + {{ form_row(form.description) }} + {{ form_row(form.vendorAddress) }} + + {{ sylius_template_event('sylius.shop.account.profile.update.form', {'vendor': vendor, 'form': form}) }} + + + {{ form_row(form._token) }} + {{ form_end(form, {'render_rest': false}) }} +
+{% endblock %} + +{% block javascripts %} + {{ parent() }} + +{% endblock %} + diff --git a/OpenMarketplace/templates/Context/Vendor/Register/_form.html.twig b/OpenMarketplace/templates/Context/Vendor/Register/_form.html.twig new file mode 100644 index 0000000..c563fdf --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Register/_form.html.twig @@ -0,0 +1,33 @@ +
+ {{ sylius_template_event('sylius.shop.register.before_form') }} + + {{ form_start(form, {'action': path('open_marketplace_vendor_register_form'), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate'}}) }} +

{{ 'open_marketplace.ui.become_a_vendor'|trans }}

+ {{ form_row(form.companyName, sylius_test_form_attribute('companyName')) }} + {{ form_row(form.taxIdentifier) }} + {{ form_row(form.bankAccountNumber) }} + {{ form_row(form.phoneNumber) }} +
+ {% form_theme form 'Context/Vendor/ProductListing/form/theme/image_theme.html.twig' %} + + {{ form_row(form.image, {'label': false}) }} +
+ +
+ {% form_theme form 'Context/Vendor/ProductListing/form/theme/image_theme.html.twig' %} + + {{ form_row(form.backgroundImage, {'label': false}) }} +
+ + {{ form_row(form.description) }} + {{ form_row(form.vendorAddress) }} + + {{ sylius_template_event('sylius.shop.register.form', {'form': form}) }} + + + + {{ form_row(form._token) }} + {{ form_end(form, {'render_rest': false}) }} +
diff --git a/OpenMarketplace/templates/Context/Vendor/Register/index.html.twig b/OpenMarketplace/templates/Context/Vendor/Register/index.html.twig new file mode 100644 index 0000000..430ed57 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Register/index.html.twig @@ -0,0 +1,18 @@ +{% extends "@SyliusShop/Account/dashboard.html.twig" %} +{% form_theme form '@SyliusShop/Form/theme.html.twig' %} +{% block subcontent %} + {% if null == app.user.vendor %} + {{ include('Context/Vendor/Register/_form.html.twig') }} + {% elseif app.user.vendor.verified %} + {% set vars = {messageTranslationKey: 'open_marketplace.ui.vendor_verification_accepted'} %} + {% include 'Context/Vendor/_Alert/infoMessage.html.twig' with vars %} + {% else %} + {% set vars = {messageTranslationKey: 'open_marketplace.ui.vendor_under_verification'} %} + {% include 'Context/Vendor/_Alert/infoMessage.html.twig' with vars %} + {% endif %} +{% endblock %} + +{% block javascripts %} + {{ parent() }} + +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/Settlement/_form.html.twig b/OpenMarketplace/templates/Context/Vendor/Settlement/_form.html.twig new file mode 100644 index 0000000..b9b8328 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Settlement/_form.html.twig @@ -0,0 +1,29 @@ +{% include "Context/Vendor/_header.html.twig" with { + "header": 'open_marketplace.ui.virtual_wallets', + "subheader": 'open_marketplace.ui.manage_your_wallets', + "icon": 'credit card' +} %} + +{{ form_start(form, { 'attr': {'class': 'ui form dirtylisten'}}) }} +{% include '@SyliusAdmin/Crud/form_validation_errors_checker.html.twig' %} +
+ {{ form_errors(form) }} +
+ +
+
+

+ {% set balance = bitbag_open_marketplace_settlement_virtual_wallet_balance_by_channel(channel)%} + {{ "open_marketplace.ui.virtual_wallet_balance"|trans }} : + {{ balance|sylius_format_money(channel.baseCurrency.code, sylius_base_locale) }} +

+
+
+ {{ form_row(form.totalAmount) }} +
+
+ {{ form_widget(form.save) }} + {{ form_row(form._token) }} +
+
+{{ form_end(form, {'render_rest': true}) }} diff --git a/OpenMarketplace/templates/Context/Vendor/Settlement/_menu.html.twig b/OpenMarketplace/templates/Context/Vendor/Settlement/_menu.html.twig new file mode 100644 index 0000000..f67ab27 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Settlement/_menu.html.twig @@ -0,0 +1,10 @@ +
+
+ {% if has_vendor_virtual_wallet_strategy() %} + + + {{ 'open_marketplace.ui.my_wallets'|trans }} + + {% endif %} +
+
diff --git a/OpenMarketplace/templates/Context/Vendor/Settlement/create.html.twig b/OpenMarketplace/templates/Context/Vendor/Settlement/create.html.twig new file mode 100644 index 0000000..93ad65c --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Settlement/create.html.twig @@ -0,0 +1,33 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} + +{% set header = configuration.vars.header|default(metadata.applicationName~'.ui.new_'~metadata.name) %} +{% set event_prefix = metadata.applicationName ~ '.vendor.' ~ metadata.name ~ '.create' %} + +{% block title %}{{ header|trans }} {{ parent() }}{% endblock %} + +{% form_theme form '@SyliusShop/Form/theme.html.twig' %} + +{% block breadcrumb %} + +{% endblock %} + +{% block subcontent %} + {{ include('Context/Vendor/Settlement/_form.html.twig') }} +{% endblock %} + +{% block stylesheets %} + {{ parent() }} + {{ sylius_template_event([event_prefix ~ '.stylesheets', 'sylius.admin.create.stylesheets'], { 'metadata': metadata }) }} +{% endblock %} + +{% block javascripts %} + {{ encore_entry_script_tags('admin-entry', null, 'admin') }} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/Settlement/index.html.twig b/OpenMarketplace/templates/Context/Vendor/Settlement/index.html.twig new file mode 100644 index 0000000..a78adbb --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/Settlement/index.html.twig @@ -0,0 +1,19 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% block title %}{{ 'open_marketplace.ui.settlements'|trans }} | {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} +
{{ 'open_marketplace.ui.settlements'|trans }}
+{% endblock %} + +{% block subcontent %} + {% include "Context/Vendor/_header.html.twig" with { + "header": 'open_marketplace.ui.settlements', + "subheader": 'open_marketplace.ui.manage_your_finances', + "icon": 'money', + "buttons": 'Context/Vendor/Settlement/_menu.html.twig', + } %} + + {{ sylius_grid_render(resources, '@SyliusShop/Grid/_default.html.twig') }} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/ShippingMethods/index.html.twig b/OpenMarketplace/templates/Context/Vendor/ShippingMethods/index.html.twig new file mode 100644 index 0000000..ba61f2f --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/ShippingMethods/index.html.twig @@ -0,0 +1,45 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% form_theme form '@SyliusShop/Form/theme.html.twig' %} + +{% block title %}{{ 'sylius.ui.your_profile'|trans }} | {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} +
{{ 'sylius.ui.shipping_method'|trans }}
+{% endblock %} + +{% block subcontent %} + {% include "Context/Vendor/_header.html.twig" with { + "header": 'open_marketplace.ui.shipping_methods', + "subheader": 'open_marketplace.ui.manage_shipping_methods', + "icon": 'shipping', + } %} + +
+ {{ form_start(form) }} + {% for channel in form.channels %} + +
+
+
+ {% for method in channel %} +
+
+ {{ form_widget(method) }} + {{ form_label(method) }} +
+
+ {% endfor %} +
+
+
+ {% endfor %} + + + {{ form_row(form._token) }} + {{ form_end(form, {'render_rest': false}) }} +
+{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/VendorPage/_main.html.twig b/OpenMarketplace/templates/Context/Vendor/VendorPage/_main.html.twig new file mode 100644 index 0000000..94b7624 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/VendorPage/_main.html.twig @@ -0,0 +1,23 @@ +{% import '@SyliusUi/Macro/messages.html.twig' as messages %} +{% import '@SyliusUi/Macro/pagination.html.twig' as pagination %} + +{{ sylius_template_event('open_marketplace.shop.product.index.search', _context) }} + + + +{{ sylius_template_event('sylius.shop.product.index.before_list', {'products': resources.data}) }} + +{% if resources.data|length > 0 %} +
+ {% for product in resources.data %} + {% include '@SyliusShop/Product/_box.html.twig' %} + {% endfor %} +
+ + + {{ sylius_template_event('sylius.shop.product.index.before_pagination', {'products': resources.data}) }} + + {{ pagination.simple(resources.data) }} +{% else %} + {{ messages.info('sylius.ui.no_results_to_display') }} +{% endif %} diff --git a/OpenMarketplace/templates/Context/Vendor/VendorPage/_search.html.twig b/OpenMarketplace/templates/Context/Vendor/VendorPage/_search.html.twig new file mode 100644 index 0000000..183f255 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/VendorPage/_search.html.twig @@ -0,0 +1,24 @@ +{% if app.request.attributes.get('slug') is null %} +{% set slug = get_channel_main_taxon().slug %} +{% else %} +{% set slug = app.request.attributes.get('slug') %} +{% endif %} +
+
+ +
+
diff --git a/OpenMarketplace/templates/Context/Vendor/VendorPage/_sidebar.html.twig b/OpenMarketplace/templates/Context/Vendor/VendorPage/_sidebar.html.twig new file mode 100644 index 0000000..4774ce2 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/VendorPage/_sidebar.html.twig @@ -0,0 +1,14 @@ +{% if app.request.attributes.get('slug') is null %} + {% set slug = get_channel_main_taxon().slug %} + {{ render(url('open_marketplace_shop_vendor_page_partial_taxon_show_by_slug', { + 'vendor_slug': app.request.attributes.get('vendor_slug'), + 'slug': slug, + 'template': 'Context/Vendor/VendorPage/_verticalMenu.html.twig' + })) }} +{% else %} + {{ render(url('open_marketplace_shop_vendor_page_partial_taxon_show_by_slug', { + 'vendor_slug': app.request.attributes.get('vendor_slug'), + 'slug': app.request.attributes.get('slug'), + 'template': 'Context/Vendor/VendorPage/_verticalMenu.html.twig' + })) }} +{% endif %} diff --git a/OpenMarketplace/templates/Context/Vendor/VendorPage/_verticalMenu.html.twig b/OpenMarketplace/templates/Context/Vendor/VendorPage/_verticalMenu.html.twig new file mode 100644 index 0000000..7475dcb --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/VendorPage/_verticalMenu.html.twig @@ -0,0 +1,15 @@ +{{ sylius_template_event('sylius.shop.product.index.before_vertical_menu', {'taxon': taxon}) }} + + + +{{ sylius_template_event('sylius.shop.product.index.after_vertical_menu', {'taxon': taxon}) }} diff --git a/OpenMarketplace/templates/Context/Vendor/VendorPage/index.html.twig b/OpenMarketplace/templates/Context/Vendor/VendorPage/index.html.twig new file mode 100644 index 0000000..ba14e57 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/VendorPage/index.html.twig @@ -0,0 +1,55 @@ +{% extends '@SyliusShop/layout.html.twig' %} + +{% set reviewsCount = 0 %} +{% set vendor = products.definition.driverConfiguration.repository.arguments.vendor %} + +{% block content %} + +
+
+ {% if vendor.getBackgroundImage is not null %} + image broken + {% endif %} +
+
+ {% if vendor.getImage is not null %} + + {% endif %} +

{{ vendor.companyName }}

+
+
+ +
+ +

{{ vendor.getAverageRatingData()['reviewsCount'] }}

+ {% if vendor.getAverageRatingData()['reviewsCount'] == 1 %} +

{{ 'open_marketplace.ui.review'|trans }}

+ {% else %} +

{{ 'sylius.ui.reviews'|trans }}

+ {% endif %} +
+
+
+
+
+
+
+ {{ vendor.companyName }} +
+
+
+

{{ vendor.description}}

+
+
+
+ {% include 'Context/Vendor/VendorPage/_sidebar.html.twig' %} +
+
+ {% include 'Context/Vendor/VendorPage/_main.html.twig' %} +
+
+ + +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/VirtualWallet/index.html.twig b/OpenMarketplace/templates/Context/Vendor/VirtualWallet/index.html.twig new file mode 100644 index 0000000..913a397 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/VirtualWallet/index.html.twig @@ -0,0 +1,18 @@ +{% extends '@SyliusShop/Account/layout.html.twig' %} +{% use 'Context/Vendor/Common/_breadcrumb.html.twig' %} + +{% block title %}{{ 'open_marketplace.ui.virtual_wallets'|trans }} | {{ parent() }}{% endblock %} + +{% block breadcrumb_page %} +
{{ 'open_marketplace.ui.virtual_wallets'|trans }}
+{% endblock %} + +{% block subcontent %} + {% include "Context/Vendor/_header.html.twig" with { + "header": 'open_marketplace.ui.virtual_wallets', + "subheader": 'open_marketplace.ui.manage_your_wallets', + "icon": 'credit card', + } %} + + {{ sylius_grid_render(resources, '@SyliusShop/Grid/_default.html.twig') }} +{% endblock %} diff --git a/OpenMarketplace/templates/Context/Vendor/_Alert/infoMessage.html.twig b/OpenMarketplace/templates/Context/Vendor/_Alert/infoMessage.html.twig new file mode 100644 index 0000000..858dc28 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/_Alert/infoMessage.html.twig @@ -0,0 +1,14 @@ +
+

{{ 'open_marketplace.ui.become_a_vendor'|trans }}

+
+ +
+
+ {{ 'sylius.ui.info'|trans }} +
+

+ {{ messageTranslationKey |trans }} +

+
+
+
diff --git a/OpenMarketplace/templates/Context/Vendor/_header.html.twig b/OpenMarketplace/templates/Context/Vendor/_header.html.twig new file mode 100644 index 0000000..45aeef9 --- /dev/null +++ b/OpenMarketplace/templates/Context/Vendor/_header.html.twig @@ -0,0 +1,23 @@ +
+
+
+

+ +
+ {{ header|trans }} + {% if subheader is defined %} +
{{ subheader|trans }}
+ {% endif %} +
+

+
+ {% if buttons is defined %} + {% if buttonsData is not defined %} + {% set buttonsData = {} %} + {% endif %} + + {% include buttons with buttonsData %} + {% endif %} +
+ +
diff --git a/OpenMarketplace/templates/bundles/BitBagSyliusWishlistPlugin/Common/_addToWishlist.html.twig b/OpenMarketplace/templates/bundles/BitBagSyliusWishlistPlugin/Common/_addToWishlist.html.twig new file mode 100644 index 0000000..2f88d4c --- /dev/null +++ b/OpenMarketplace/templates/bundles/BitBagSyliusWishlistPlugin/Common/_addToWishlist.html.twig @@ -0,0 +1,65 @@ +{% if app.user %} + {% if findAllByShopUserAndToken(app.user)|length < 2 %} + + + {{ 'bitbag_sylius_wishlist_plugin.ui.add_to_wishlist'|trans }} + + {% else %} + + {% endif %} +{% else %} + {% if findAllByAnonymousAndChannel(sylius.channel)|length < 2 %} + + + {{ 'bitbag_sylius_wishlist_plugin.ui.add_to_wishlist'|trans }} + + {% else %} + + {% endif %} +{% endif %} + + diff --git a/OpenMarketplace/templates/bundles/SyliusAdminBundle/Layout/_logo.html.twig b/OpenMarketplace/templates/bundles/SyliusAdminBundle/Layout/_logo.html.twig new file mode 100644 index 0000000..68e7612 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusAdminBundle/Layout/_logo.html.twig @@ -0,0 +1,5 @@ + +
+ +
+
diff --git a/OpenMarketplace/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig b/OpenMarketplace/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig new file mode 100644 index 0000000..78167f1 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig @@ -0,0 +1,96 @@ +{% import "@SyliusAdmin/Common/Macro/money.html.twig" as money %} + +{% set orderShippingPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_SHIPPING_PROMOTION_ADJUSTMENT') %} +{% set shippingAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::SHIPPING_ADJUSTMENT') %} +{% set taxAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::TAX_ADJUSTMENT') %} + +{% set orderShippingPromotions = sylius_aggregate_adjustments(order.getAdjustmentsRecursively(orderShippingPromotionAdjustment)) %} + + + + + {{ 'sylius.ui.tax_total'|trans }}: + {{ money.format(order.taxTotal, order.currencyCode) }} + + + {{ 'sylius.ui.items_total'|trans }}: + {{ money.format(order.itemsTotal, order.currencyCode) }} + + + + + +

{{ 'open_marketplace.ui.commission'|trans }} ({{ 'sylius.ui.included_in_price'|trans }})

+ + + {{ 'open_marketplace.ui.commission'|trans }}: + {{ money.format(order.commissionTotal, order.currencyCode) }} + + + + + + {% if not order.adjustments(shippingAdjustment).isEmpty() %} +
+
{{ 'sylius.ui.shipping'|trans }}:
+ {% for shipment in order.shipments %} + {% for adjustment in shipment.adjustments(shippingAdjustment) %} +
+
{{ money.format(adjustment.amount, order.currencyCode) }}
+
+
+ {{ adjustment.label }}: +
+
+
+ {% endfor %} + + {% for adjustment in shipment.adjustments(taxAdjustment) %} +
+
+ {{ money.format(adjustment.amount, order.currencyCode) }} + {% if adjustment.isNeutral %} + ({{ 'sylius.ui.included_in_price'|trans }}) + {% endif %} +
+
+
+ {{ adjustment.label }}: +
+
+
+ {% endfor %} + {% endfor %} +
+ {% else %} +

{{ 'sylius.ui.no_shipping_charges'|trans }}

+ {% endif %} + + {% if not orderShippingPromotions is empty %} + +
+
{{ 'sylius.ui.shipping_discount'|trans }}:
+ {% for label, amount in orderShippingPromotions %} +
+
+ {{ money.format(amount, order.currencyCode) }} +
+
+ {% endfor %} +
+ + {% endif %} + + {{ 'sylius.ui.shipping_total'|trans }}: + {{ money.format(order.shippingTotal, order.currencyCode) }} + + + +{% include '@SyliusAdmin/Order/Show/Summary/_totalsPromotions.html.twig' %} + + + + {{ 'sylius.ui.order_total'|trans }}: + {{ money.format(order.total, order.currencyCode) }} + + diff --git a/OpenMarketplace/templates/bundles/SyliusAdminBundle/Security/_content.html.twig b/OpenMarketplace/templates/bundles/SyliusAdminBundle/Security/_content.html.twig new file mode 100644 index 0000000..ce17621 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusAdminBundle/Security/_content.html.twig @@ -0,0 +1,6 @@ +{% include '@SyliusUi/Security/_login.html.twig' + with { + 'action': path('sylius_admin_login_check'), + 'paths': {'logo': asset('build/admin/images/logo.png', 'admin')} +} +%} diff --git a/OpenMarketplace/templates/bundles/SyliusAdminBundle/Security/login.html.twig b/OpenMarketplace/templates/bundles/SyliusAdminBundle/Security/login.html.twig new file mode 100644 index 0000000..5239937 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusAdminBundle/Security/login.html.twig @@ -0,0 +1,15 @@ +{% extends '@SyliusUi/Layout/centered.html.twig' %} + +{% block title %}BitBag Open Marketplace | {{ 'sylius.ui.administration_panel_login'|trans }}{% endblock %} + +{% block stylesheets %} + {{ sylius_template_event('sylius.admin.layout.stylesheets') }} +{% endblock %} + +{% block content %} + {{ sylius_template_event('sylius.admin.login.content', _context) }} +{% endblock %} + +{% block javascripts %} + {{ sylius_template_event('sylius.admin.layout.javascripts') }} +{% endblock %} diff --git a/OpenMarketplace/templates/bundles/SyliusAdminBundle/_scripts.html.twig b/OpenMarketplace/templates/bundles/SyliusAdminBundle/_scripts.html.twig new file mode 100644 index 0000000..77e26d2 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusAdminBundle/_scripts.html.twig @@ -0,0 +1,3 @@ +{{ encore_entry_script_tags('admin-entry', null, 'admin') }} +{{ encore_entry_script_tags('bitbag-cms-admin', null, 'cms_admin') }} +{{ encore_entry_script_tags('bitbag-wishlist-admin', null, 'wishlist_admin') }} diff --git a/OpenMarketplace/templates/bundles/SyliusAdminBundle/_styles.html.twig b/OpenMarketplace/templates/bundles/SyliusAdminBundle/_styles.html.twig new file mode 100644 index 0000000..12e5e3f --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusAdminBundle/_styles.html.twig @@ -0,0 +1,3 @@ +{{ encore_entry_link_tags('admin-entry', null, 'admin') }} +{{ encore_entry_link_tags('bitbag-cms-admin', null, 'cms_admin') }} +{{ encore_entry_link_tags('bitbag-wishlist-admin', null, 'wishlist_admin') }} diff --git a/OpenMarketplace/templates/bundles/SyliusAdminBundle/layout.html.twig b/OpenMarketplace/templates/bundles/SyliusAdminBundle/layout.html.twig new file mode 100644 index 0000000..266cc75 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusAdminBundle/layout.html.twig @@ -0,0 +1,39 @@ +{% extends '@SyliusUi/Layout/sidebar.html.twig' %} + +{% block title %} | BitBag OpenMarketplace{% endblock %} + +{% block metatags %} + +{% endblock %} + +{% block stylesheets %} + {{ sylius_template_event('sylius.admin.layout.stylesheets') }} +{% endblock %} + +{% block flash_messages %} + {% include '@SyliusAdmin/_flashes.html.twig' %} +{% endblock %} + +{% block topbar %} + {{ sylius_template_event('sylius.admin.layout.topbar_left') }} + +
+ + {{ sylius_template_event('sylius.admin.layout.topbar_middle') }} + +
+ + {{ sylius_template_event('sylius.admin.layout.topbar_right') }} +{% endblock %} + +{% block sidebar %} + {{ sylius_template_event('sylius.admin.layout.sidebar') }} +{% endblock %} + +{% block footer %} + {{ 'sylius.ui.powered_by'|trans }} Sylius v{{ sylius_meta.version }}. {{ 'sylius.ui.see_issue'|trans }}? {{ 'sylius.ui.report_it'|trans }}! +{% endblock %} + +{% block javascripts %} + {{ sylius_template_event('sylius.admin.layout.javascripts') }} +{% endblock %} diff --git a/OpenMarketplace/templates/bundles/SyliusCoreBundle/Email/Blocks/OrderConfirmation/_content.html.twig b/OpenMarketplace/templates/bundles/SyliusCoreBundle/Email/Blocks/OrderConfirmation/_content.html.twig new file mode 100644 index 0000000..11b63db --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusCoreBundle/Email/Blocks/OrderConfirmation/_content.html.twig @@ -0,0 +1,33 @@ +
+ {{ 'sylius.email.order_confirmation.your_order_number'|trans({}, null, localeCode) }} +
+ {% if order.primary %} + {% for suborder in order.secondaryOrders %} + + {{ suborder.number }} + + {% endfor %} + {% else %} + + {{ order.number }} + + {% endif %} + +
+ {{ 'sylius.email.order_confirmation.has_been_successfully_placed'|trans({}, null, localeCode) }} +
+ +{% if sylius_bundle_loaded_checker('SyliusShopBundle') %} + {% set url = channel.hostname is not null ? 'http://' ~ channel.hostname ~ path('sylius_shop_order_show', {'tokenValue': order.tokenValue, '_locale': localeCode}) : url('sylius_shop_order_show', {'tokenValue': order.tokenValue, '_locale': localeCode}) %} + + +{% endif %} + +
+ {{ 'sylius.email.order_confirmation.thank_you'|trans({}, null, localeCode) }} +
diff --git a/OpenMarketplace/templates/bundles/SyliusCoreBundle/Email/layout.html.twig b/OpenMarketplace/templates/bundles/SyliusCoreBundle/Email/layout.html.twig new file mode 100644 index 0000000..824d9c4 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusCoreBundle/Email/layout.html.twig @@ -0,0 +1,28 @@ +{% block body %} + {% autoescape false %} + {% set logo = channel.hostname is not null ? 'http://' ~ channel.hostname ~ asset('open-marketplace-logo.png') : absolute_url(asset('open-marketplace-logo.png')) %} + +
+
+
+ {% if sylius_bundle_loaded_checker('SyliusShopBundle') %} + {% set url = channel.hostname is not null ? 'http://' ~ channel.hostname ~ path('sylius_shop_homepage', {'_locale': localeCode}) : url('sylius_shop_homepage', {'_locale': localeCode}) %} + + OpenMarketplace + + {% else %} + OpenMarketplace + {% endif %} +
+ +
+ {% block content %}{% endblock %} +
+ + +
+
+ {% endautoescape %} +{% endblock %} diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/Account/Order/Show/_header.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/Account/Order/Show/_header.html.twig new file mode 100644 index 0000000..a1a438b --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/Account/Order/Show/_header.html.twig @@ -0,0 +1,29 @@ +{% import '@SyliusUi/Macro/buttons.html.twig' as buttons %} +{% import '@SyliusUi/Macro/flags.html.twig' as flags %} + +

+ +
+ {{ 'sylius.ui.order'|trans }} #{{ order.number }} +
+
+
+ {{ order.checkoutCompletedAt|format_date }} +
+
+ {% include [('@SyliusShop/Account/Order/Label/State' ~ '/' ~ order.state ~ '.html.twig'), '@SyliusUi/Label/_default.html.twig'] with {'value': ('sylius.ui.' ~ order.state)|trans} %} +
+
+ {{ order.currencyCode }} +
+
+ {{ flags.fromLocaleCode(order.localeCode) }}{{ order.localeCode|sylius_locale_name }} +
+
+
+
+

+ +{% if order.paymentState in ['awaiting_payment'] %} + {{ buttons.default(path('sylius_shop_order_show', {'tokenValue': order.primaryOrder.tokenValue}), 'sylius.ui.pay', null, 'credit card alternative', 'fluid blue') }} +{% endif %} diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/Cart/Summary/_items.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/Cart/Summary/_items.html.twig new file mode 100644 index 0000000..66b17ef --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/Cart/Summary/_items.html.twig @@ -0,0 +1,34 @@ +
+ {{ form_start(form, {'action': path('sylius_shop_cart_save'), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} + {{ form_errors(form) }} + + {{ form_row(form._token) }} + {{ form_end(form, {'render_rest': false}) }} + + {{ sylius_template_event('sylius.shop.cart.summary.items', {'cart': cart, 'form': form}) }} + + + + + + + + + + + + {% for key, item in cart.items %} + + {% include 'Context/Shop/Cart/Summary/_item.html.twig' with {'item': item, 'form': form.items[key], 'main_form': form.vars.id, 'loop_index': loop.index} %} + {% endfor %} + +
{{ 'sylius.ui.item'|trans }}{{ 'sylius.ui.unit_price'|trans }}{{ 'sylius.ui.qty'|trans }}{{ 'sylius.ui.total'|trans }}
+ {% if form.promotionCoupon is defined %} + + + {{ sylius_template_event('sylius.shop.cart.coupon', {'cart': cart, 'form': form, 'main_form': form.vars.id}) }} + + {% endif %} + + {% include '@SyliusShop/Cart/Summary/_update.html.twig' with {'main_form': form.vars.id} %} +
diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/Checkout/_header.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/Checkout/_header.html.twig new file mode 100644 index 0000000..43c1dc6 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/Checkout/_header.html.twig @@ -0,0 +1,30 @@ +
+ +
diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/Homepage/_banner.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/Homepage/_banner.html.twig new file mode 100644 index 0000000..bb594f7 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/Homepage/_banner.html.twig @@ -0,0 +1,2 @@ +Sylius + diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/Layout/Footer/Grid/_plus.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/Layout/Footer/Grid/_plus.html.twig new file mode 100644 index 0000000..26afe2b --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/Layout/Footer/Grid/_plus.html.twig @@ -0,0 +1,7 @@ + diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/Layout/Footer/_content.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/Layout/Footer/_content.html.twig new file mode 100644 index 0000000..82c1b1b --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/Layout/Footer/_content.html.twig @@ -0,0 +1,9 @@ +
+
{{ 'open_marketplace.ui.footer_signature'|trans }}
+ + + + + + +
diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/Layout/Header/_logo.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/Layout/Header/_logo.html.twig new file mode 100644 index 0000000..6e619de --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/Layout/Header/_logo.html.twig @@ -0,0 +1,5 @@ + diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/Order/_summary.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/Order/_summary.html.twig new file mode 100644 index 0000000..a03aec4 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/Order/_summary.html.twig @@ -0,0 +1,28 @@ +{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} + +

+ +
+ {{ 'open_marketplace.ui.summary_of_your_order'|trans }} + {% if order.primary %} + {% for suborder in order.secondaryOrders %} + #{{ suborder.number }} + {% endfor %} + {% else %} + #{{ order.number }} + {% endif %} +
+
+
+ {{ order.checkoutCompletedAt|date }} +
+
+ {{ money.convertAndFormat(order.total) }} +
+
+ {{ order.totalQuantity }} {{ 'sylius.ui.items'|trans|lower }} +
+
+
+
+

diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/Show/_addToCart.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/Show/_addToCart.html.twig new file mode 100644 index 0000000..9a152b0 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/Show/_addToCart.html.twig @@ -0,0 +1,59 @@ +{% set product = order_item.variant.product %} + +{% form_theme form '@SyliusShop/Form/theme.html.twig' %} + +
+ {{ sonata_block_render_event('sylius.shop.product.show.before_add_to_cart', {'product': product, 'order_item': order_item}) }} + + {{ form_start(form, { + 'action': path('sylius_shop_ajax_cart_add_item', {'productId': product.id}), + 'attr': { + 'id': 'sylius-product-adding-to-cart', + 'class': 'ui loadable form', + 'novalidate': 'novalidate', + 'data-redirect': path(configuration.getRedirectRoute('summary')) + } + }) }} + + {{ form_errors(form) }} + + + + {% if not product.simple %} + {% if product.variantSelectionMethodChoice %} + {% include '@SyliusShop/Product/Show/_variants.html.twig' %} + {% else %} + {% include '@SyliusShop/Product/Show/_options.html.twig' %} + {% endif %} + {% endif %} + + {{ form_row(form.cartItem.quantity) }} + + {{ sonata_block_render_event('sylius.shop.product.show.add_to_cart_form', { + 'product': product, + 'order_item': order_item + }) }} + + {{ form_widget(form.wishlists) }} +
+ {% if product.getVendor() is null or product.getVendor().isEnabled() %} + + {% endif %} + + + + {{ form_row(form._token) }} + {{ form_end(form, {'render_rest': false}) }} +
diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/Show/_images.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/Show/_images.html.twig new file mode 100644 index 0000000..fe2d2bf --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/Show/_images.html.twig @@ -0,0 +1,42 @@ +{% set mainPhoto = null %} + +{% if product.imagesByType('main') is not empty %} + {% set mainPhoto = product.imagesByType('main').first %} +{% elseif product.images.first %} + {% set mainPhoto = product.images.first %} +{% endif %} + +{% if mainPhoto is not null %} + {% set source_path = mainPhoto.path %} + {% set original_path = source_path|imagine_filter('sylius_shop_product_original') %} + {% set path = source_path|imagine_filter(filter|default('sylius_shop_product_large_thumbnail')) %} +{% else %} + {% set original_path = asset('assets/shop/img/400x300.png') %} + {% set path = original_path %} +{% endif %} + +
+ + {{ product.name }} + +{% if product.images|length > 1 %} +
+ + {{ sylius_template_event('sylius.shop.product.show.before_thumbnails', {'product': product}) }} + +
+ {% for image in product.images if mainPhoto != image %} + {% set path = image.path is not null + ? image.path|imagine_filter('sylius_shop_product_small_thumbnail') + : asset('assets/shop/img/200x200.png') %} +
+ {% if product.isConfigurable() and product.enabledVariants|length > 0 %} + {% include '@SyliusShop/Product/Show/_imageVariants.html.twig' %} + {% endif %} + + {{ product.name }} + +
+ {% endfor %} +
+{% endif %} diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/Show/_inventory.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/Show/_inventory.html.twig new file mode 100644 index 0000000..3661478 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/Show/_inventory.html.twig @@ -0,0 +1,6 @@ +{% if product.enabledVariants.empty() or product.simple and not sylius_inventory_is_available(product.enabledVariants.first) %} + {{ render(url('sylius_shop_partial_cart_add_item', {'template': '@SyliusShop/Product/Show/_outOfStock.html.twig', 'productId': product.id })) }} + {% include '@BitBagSyliusWishlistPlugin/Common/_addToWishlist.html.twig' %} +{% else %} + {{ render(url('sylius_shop_partial_cart_add_item', {'template': '@SyliusShop/Product/Show/_addToCart.html.twig', 'productId': product.id})) }} +{% endif %} diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/Show/_outOfStock.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/Show/_outOfStock.html.twig new file mode 100644 index 0000000..958a20e --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/Show/_outOfStock.html.twig @@ -0,0 +1,6 @@ +
+ +
+ {{ 'sylius.ui.out_of_stock'|trans }} +
+
diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/Show/_reviews.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/Show/_reviews.html.twig new file mode 100644 index 0000000..4be6376 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/Show/_reviews.html.twig @@ -0,0 +1,13 @@ + diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/_box.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/_box.html.twig new file mode 100644 index 0000000..d07f3ea --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/Product/_box.html.twig @@ -0,0 +1,33 @@ +{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} + +{{ sonata_block_render_event('sylius.shop.product.index.before_box', {'product': product}) }} + +
+ +
+
+
+
{{ 'sylius.ui.view_more'|trans }}
+
+
+
+ {% include '@SyliusShop/Product/_mainImage.html.twig' with {'product': product} %} +
+
+ {{ product.name }} + + {% if not product.enabledVariants.empty() %} +
{{ money.calculatePrice(product|sylius_resolve_variant) }}
+ {% endif %} + +
+ + {% include '@BitBagSyliusWishlistPlugin/Common/_addToWishlist.html.twig' %} +
+
+ +{{ sonata_block_render_event('sylius.shop.product.index.after_box', {'product': product}) }} diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/Taxon/_horizontalMenu.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/Taxon/_horizontalMenu.html.twig new file mode 100644 index 0000000..0b61766 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/Taxon/_horizontalMenu.html.twig @@ -0,0 +1,27 @@ +{% macro item(taxon) %} + {% import _self as macros %} + {% if taxon.isEnabled() %} + {% if taxon.children|length > 0 %} + + {% else %} + {{ taxon.name }} + {% endif %} + {% endif %} +{% endmacro %} + +{% import _self as macros %} + +{% if taxons|length > 0 %} + {% for taxon in taxons %} + {{ macros.item(taxon) }} + {% endfor %} +{% endif %} diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/_header.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/_header.html.twig new file mode 100644 index 0000000..ce327f5 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/_header.html.twig @@ -0,0 +1,12 @@ +
+
+ {% include "@SyliusShop/Layout/Header/_logo.html.twig" %} +
+ {{ sonata_block_render_event('sylius.shop.layout.header') }} +
+
+ {{ render(url('bitbag_sylius_wishlist_plugin_shop_wishlist_render_header_template')) }} + {{ render(url('sylius_shop_partial_cart_summary', {'template': '@SyliusShop/Cart/_widget.html.twig'})) }} +
+
+
diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/_scripts.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/_scripts.html.twig new file mode 100644 index 0000000..4437be1 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/_scripts.html.twig @@ -0,0 +1,3 @@ +{{ encore_entry_script_tags('shop-entry', null, 'shop') }} +{{ encore_entry_script_tags('bitbag-cms-shop', null, 'cms_shop') }} +{{ encore_entry_script_tags('bitbag-wishlist-shop', null, 'wishlist_shop') }} diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/_styles.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/_styles.html.twig new file mode 100644 index 0000000..3f8b68a --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/_styles.html.twig @@ -0,0 +1,3 @@ +{{ encore_entry_link_tags('shop-entry', null, 'shop') }} +{{ encore_entry_link_tags('bitbag-cms-shop', null, 'cms_shop') }} +{{ encore_entry_link_tags('bitbag-wishlist-shop', null, 'wishlist_shop') }} diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/layout.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/layout.html.twig new file mode 100755 index 0000000..9464904 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/layout.html.twig @@ -0,0 +1,139 @@ + + + + + + + + {% block title %}BitBag OpenMarketplace{% endblock %} + + + + + {% block metatags %} + {% endblock %} + + {% block stylesheets %} + + + + + {{ sonata_block_render_event('sylius.shop.layout.stylesheets') }} + {{ sylius_template_event('sylius.shop.layout.stylesheets') }} + {% endblock %} + + {{ sonata_block_render_event('sylius.shop.layout.head') }} + + + +{{ sonata_block_render_event('sylius.shop.layout.before_body') }} +
+ {% block top %} + + {% endblock %} +
+ {% block header %} +
+ {% include '@SyliusShop/_header.html.twig' %} + + {{ sonata_block_render_event('sylius.shop.layout.after_header') }} + + +
+ {% endblock %} + + {% include '@SyliusUi/_flashes.html.twig' %} + + {{ sonata_block_render_event('sylius.shop.layout.before_content') }} + + {% block content %} + {% endblock %} + + {{ sonata_block_render_event('sylius.shop.layout.after_content') }} +
+ + {% block footer %} + {% include '@SyliusShop/_footer.html.twig' %} + {% endblock %} +
+ +{% block javascripts %} + {% include '@SyliusUi/_javascripts.html.twig' with {'path': 'assets/shop/js/app.js'} %} + {{ sylius_template_event('sylius.shop.layout.javascripts') }} + {{ sonata_block_render_event('sylius.shop.layout.javascripts') }} +{% endblock %} + +{% include '@SyliusUi/Modal/_confirmation.html.twig' %} +{{ sonata_block_render_event('sylius.shop.layout.after_body') }} + + diff --git a/OpenMarketplace/templates/bundles/SyliusShopBundle/login.html.twig b/OpenMarketplace/templates/bundles/SyliusShopBundle/login.html.twig new file mode 100644 index 0000000..042120b --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusShopBundle/login.html.twig @@ -0,0 +1,24 @@ +{% extends '@SyliusShop/layout.html.twig' %} + +{% form_theme form '@SyliusShop/Form/theme.html.twig' %} + +{% block title %}{{ 'sylius.ui.customer_login'|trans }} | {{ parent() }}{% endblock %} + +{% block content %} + {% include '@SyliusShop/Login/_header.html.twig' %} + {% include 'Context/Vendor/Login/_vendorDefaultCredentials.html.twig' %} + {{ sylius_template_event('sylius.shop.login.after_content_header') }} + +
+
+
+ {{ sylius_template_event('sylius.shop.login.main_column', _context) }} +
+ +
+ {{ sylius_template_event('sylius.shop.login.register_column', _context) }} +
+
+
+{% endblock %} diff --git a/OpenMarketplace/templates/bundles/SyliusUiBundle/Layout/centered.html.twig b/OpenMarketplace/templates/bundles/SyliusUiBundle/Layout/centered.html.twig new file mode 100644 index 0000000..76a2ca4 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusUiBundle/Layout/centered.html.twig @@ -0,0 +1,36 @@ + + + + + + + + {% block title %}BitBag OpenMarketplace{% endblock %} + + + + + {% block metatags %} + {% endblock %} + + {% block stylesheets %} + + {% endblock %} + + +{% block pre_content %} +{% endblock %} + +{% block content %} +{% endblock %} + +{% block post_content %} +{% endblock %} + +{% block javascripts %} +{% endblock %} + + diff --git a/OpenMarketplace/templates/bundles/SyliusUiBundle/Modal/_confirmation.html.twig b/OpenMarketplace/templates/bundles/SyliusUiBundle/Modal/_confirmation.html.twig new file mode 100644 index 0000000..1ab5dfa --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusUiBundle/Modal/_confirmation.html.twig @@ -0,0 +1,19 @@ + diff --git a/OpenMarketplace/templates/bundles/SyliusUiBundle/Security/_logo.html.twig b/OpenMarketplace/templates/bundles/SyliusUiBundle/Security/_logo.html.twig new file mode 100644 index 0000000..db48876 --- /dev/null +++ b/OpenMarketplace/templates/bundles/SyliusUiBundle/Security/_logo.html.twig @@ -0,0 +1,5 @@ +{% if paths.logo is defined %} +
+ +
+{% endif %} diff --git a/OpenMarketplace/templates/bundles/TwigBundle/Exception/error.html.twig b/OpenMarketplace/templates/bundles/TwigBundle/Exception/error.html.twig new file mode 100644 index 0000000..2024e9f --- /dev/null +++ b/OpenMarketplace/templates/bundles/TwigBundle/Exception/error.html.twig @@ -0,0 +1,19 @@ +{% extends '@SyliusShop/layout.html.twig' %} + +{% block content %} +
+
+
+ BitBag OpenMarketplace logo +
+

+ {% block error_message %} + {{ 'sylius.ui.unexpected_error_occurred'|trans }} + {% endblock %} +

+ {{ 'sylius.ui.back_to_store'|trans }} +
+
+
+
+{% endblock %} diff --git a/OpenMarketplace/templates/bundles/TwigBundle/Exception/error403.html.twig b/OpenMarketplace/templates/bundles/TwigBundle/Exception/error403.html.twig new file mode 100644 index 0000000..dcb2688 --- /dev/null +++ b/OpenMarketplace/templates/bundles/TwigBundle/Exception/error403.html.twig @@ -0,0 +1,5 @@ +{% extends '@Twig/Exception/error.html.twig' %} + +{% block error_message %} + {{ 'sylius.ui.the_page_you_are_looking_for_is_forbidden'|trans }} +{% endblock %} diff --git a/OpenMarketplace/templates/bundles/TwigBundle/Exception/error404.html.twig b/OpenMarketplace/templates/bundles/TwigBundle/Exception/error404.html.twig new file mode 100644 index 0000000..d38c585 --- /dev/null +++ b/OpenMarketplace/templates/bundles/TwigBundle/Exception/error404.html.twig @@ -0,0 +1,5 @@ +{% extends '@Twig/Exception/error.html.twig' %} + +{% block error_message %} + {{ 'sylius.ui.the_page_you_are_looking_for_does_not_exist'|trans }} +{% endblock %} diff --git a/OpenMarketplace/tests/Behat/Context/Common/GridSortingContext.php b/OpenMarketplace/tests/Behat/Context/Common/GridSortingContext.php new file mode 100644 index 0000000..371febc --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Common/GridSortingContext.php @@ -0,0 +1,45 @@ + 'asc', + 'descending' => 'desc', + ]; + + private const SORTING = 'sorting'; + + public function __construct( + private SharedStorageInterface $sharedStorage, + ) { + } + + /** + * @Then I sort the list by :sortField in :value order + */ + public function iSortTheListByInOrder($sortField, $value): void + { + $this->sharedStorage->set( + self::SORTING, + [ + self::SORTING => [ + $sortField => self::SORT_TYPES[$value], + ], + ] + ); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/ConversationContext.php b/OpenMarketplace/tests/Behat/Context/ConversationContext.php new file mode 100644 index 0000000..9bc620b --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/ConversationContext.php @@ -0,0 +1,103 @@ +manager = $manager; + $this->vendorProfileFactory = $vendorProfileFactory; + $this->userFactory = $userFactory; + $this->addressFactory = $addressFactory; + $this->sharedStorage = $sharedStorage; + $this->userRepository = $userRepository; + } + + /** + * @Given there is a vendor user :vendor_user_email registered in country :country_code + */ + public function thereIsAVendorUserRegisteredInCountry($vendor_user_email, $country_code): void + { + $user = $this->userFactory->create(['email' => $vendor_user_email, 'password' => 'password', 'enabled' => true]); + $country = $this->manager->getRepository(Country::class)->findOneBy(['code' => $country_code]); + $this->sharedStorage->set('user', $user); + + $this->userRepository->add($user); + $address = $this->addressFactory->createAddress('Grand avenue', 'Berlin', '22-111', $country); + + $vendor = $this->vendorProfileFactory->createVendor( + 'someCompany', + 'TaxID', + 'iban', + '333222111', + 'description', + $address + ); + + $vendor->setSlug('vendor-slug'); + $vendor->setShopUser($user); + $this->manager->persist($vendor); + $this->manager->flush(); + $this->sharedStorage->set('vendor', $vendor); + } + + /** + * @Given there is conversation category :categoryName + */ + public function thereIsConversationCategory($categoryName) + { + $category = new Category(); + $category->setName($categoryName); + $this->manager->persist($category); + $this->manager->flush(); + } + + /** + * @return DocumentElement + */ + private function getPage() + { + return $this->getSession()->getPage(); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Setup/AdminUserContext.php b/OpenMarketplace/tests/Behat/Context/Setup/AdminUserContext.php new file mode 100644 index 0000000..b06abb2 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Setup/AdminUserContext.php @@ -0,0 +1,37 @@ +adminUserExample->create(); + $admin->setUsername($username); + $admin->setPlainPassword($password); + $this->entityManager->persist($admin); + $this->entityManager->flush(); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Setup/DraftAttributeContext.php b/OpenMarketplace/tests/Behat/Context/Setup/DraftAttributeContext.php new file mode 100644 index 0000000..5a254d0 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Setup/DraftAttributeContext.php @@ -0,0 +1,42 @@ +sharedStorage->get('vendor'); + $draftAttribute = $this->draftAttributeFactory->createTyped($type, $vendor); + $draftAttribute->setCode($code); + + $this->sharedStorage->set(sprintf('draft_attribute_%s', $code), $draftAttribute); + $this->entityManager->persist($draftAttribute); + + $this->entityManager->flush(); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Setup/Factory/VendorFactory.php b/OpenMarketplace/tests/Behat/Context/Setup/Factory/VendorFactory.php new file mode 100644 index 0000000..cb6d32d --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Setup/Factory/VendorFactory.php @@ -0,0 +1,41 @@ +setCompanyName($companyName); + $vendor->setTaxIdentifier($taxIdentifier); + $vendor->setPhoneNumber($phoneNumber); + $vendor->setSlug($slug); + $vendor->setDescription($description); + $vendor->setStatus($status); + $vendor->setEditedAt(null); + + return $vendor; + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Setup/Factory/VendorFactoryInterface.php b/OpenMarketplace/tests/Behat/Context/Setup/Factory/VendorFactoryInterface.php new file mode 100644 index 0000000..1beb94a --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Setup/Factory/VendorFactoryInterface.php @@ -0,0 +1,28 @@ +createVirtualWallet($channel, $vendor, $customer); + $shopUser = $vendor->getShopUser(); + $customer = $shopUser->getCustomer(); + Assert::isInstanceOf($customer, CustomerInterface::class); + + $order = $this->orderExampleFactory->createOrderWithTotalAmount( + $channel, + $vendor, + $customer, + $balance, + ); + + $virtualWallet->stash($order); + + return $virtualWallet; + } + + public function createVirtualWallet( + ChannelInterface $channel, + VendorInterface $vendor, + CustomerInterface $customer, + ): VirtualWalletInterface { + $virtualWallet = new VirtualWallet(); + $virtualWallet->setChannel($channel); + $virtualWallet->setVendor($vendor); + + return $virtualWallet; + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Setup/Factory/VirtualWalletFactoryInterface.php b/OpenMarketplace/tests/Behat/Context/Setup/Factory/VirtualWalletFactoryInterface.php new file mode 100644 index 0000000..fc1644b --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Setup/Factory/VirtualWalletFactoryInterface.php @@ -0,0 +1,33 @@ +sharedStorage->get('vendor'); + + $order = $this->createDefaultOrder(); + $order->setVendor($vendor); + + if (str_contains($propertyName, 'CompletedAt')) { + $date = new \DateTime($value); + $order->{'set' . ucfirst($propertyName)}($date); + } else { + $order->{'set' . ucfirst($propertyName)}($value); + } + + $this->sharedStorage->set('order', $order); + + $this->orderRepository->add($order); + } + + /** + * @Given There is order with property :propertyName with value :value made with other seller + */ + public function thereIsOrderWithPropertyWithValueMadeWithSomeSeller( + string $propertyName, + string $value + ): void { + $vendor = $this->createDefaultVendor(); + + $order = $this->createDefaultOrder(); + $order->setVendor($vendor); + + if (str_contains($propertyName, 'CompletedAt')) { + $date = new \DateTime($value); + $order->{'set' . ucfirst($propertyName)}($date); + } else { + $order->{'set' . ucfirst($propertyName)}($value); + } + + $this->sharedStorage->set('order', $order); + + $this->orderRepository->add($order); + } + + /** + * @Given The order is made by customer with first name :firstName + */ + public function theOrderIsMadeByCustomerWithFirstName(string $firstName): void + { + $order = $this->sharedStorage->get('order'); + $client = $order->getCustomer(); + $client->setFirstName($firstName); + $this->entityManager->persist($client); + $this->entityManager->flush(); + $this->sharedStorage->set('order', $order); + } + + /** + * @Given There is :count orders made with logged in seller + */ + public function thereIsOrdersMadeWithLoggedInSeller($count) + { + $vendor = $this->sharedStorage->get('vendor'); + $orders = []; + + for ($i = 0; $i < $count; ++$i) { + $orders[$i] = $this->createDefaultOrder(); + $orders[$i]->setVendor($vendor); + + $this->orderRepository->add($orders[$i]); + } + $this->sharedStorage->set('orders', $orders); + } + + /** + * @Given /^(this order) has new shipment$/ + */ + public function thisOrderHasNewShipment(OrderInterface $order): void + { + $shippingMethod = $this->shippingMethodRepository->findOneBy([]); + Assert::notEmpty($shippingMethod); + + $shipment = $this->shipmentFactory->createNew(); + $shipment->setMethod($shippingMethod); + $shipment->setOrder($order); + $order->addShipment($shipment); + + $this->stateMachineFactory->get($order, OrderShippingTransitions::GRAPH)->apply(OrderShippingTransitions::TRANSITION_REQUEST_SHIPPING); + $this->applyShipmentTransitionOnOrder($order, ShipmentTransitions::TRANSITION_CREATE); + + $this->entityManager->flush(); + } + + /** + * @Given /^(this order) has already been shipped$/ + */ + public function thisOrderHasAlreadyBeenShipped(OrderInterface $order): void + { + $this->stateMachineFactory->get($order, OrderShippingTransitions::GRAPH)->apply(OrderShippingTransitions::TRANSITION_SHIP); + $this->applyShipmentTransitionOnOrder($order, ShipmentTransitions::TRANSITION_SHIP); + + $this->entityManager->flush(); + } + + /** + * @Given this order has new shipping address city: :city, postalCode: :postalCode, street: :street + */ + public function thisOrderHasNewShippingAddressCityPostalCodeStreet( + string $city, + string $postalCode, + string $street + ): void { + $country = $this->entityManager->getRepository(Country::class)->findOneBy([]); + Assert::notEmpty($country); + + /** @var OrderInterface $order */ + $order = $this->sharedStorage->get('order'); + $customer = $order->getCustomer(); + $order->setShippingAddress($this->createAddress($customer, $country, $city, $postalCode, $street)); + $this->entityManager->flush(); + } + + /** + * @Given this order has new billing address city: :city, postalCode: :postalCode, street: :street + */ + public function thisOrderHasNewBillingAddressCityPostalCodeStreet( + string $city, + string $postalCode, + string $street + ): void { + $country = $this->entityManager->getRepository(Country::class)->findOneBy([]); + Assert::notEmpty($country); + + /** @var OrderInterface $order */ + $order = $this->sharedStorage->get('order'); + $customer = $order->getCustomer(); + $order->setBillingAddress($this->createAddress($customer, $country, $city, $postalCode, $street)); + $this->entityManager->flush(); + } + + /** + * @Given The customer :customer has new order + */ + public function thereIsFulfilledOrder(string $customer): void + { + $orders = $this->orderExampleFactory->createArray(['customer' => $customer]); + + foreach ($orders as $order) { + $this->orderRepository->add($order); + } + + $this->sharedStorage->set('primary_order', reset($orders)); + } + + private function createOrder( + CustomerInterface $customer, + ?string $number = null, + ?ChannelInterface $channel = null, + ?string $localeCode = null + ) { + $order = $this->createCart($customer, $channel, $localeCode); + + if (null !== $number) { + $order->setNumber($number); + } + + $order->completeCheckout(); + + return $order; + } + + private function createCart( + CustomerInterface $customer, + ChannelInterface $channel = null, + string $localeCode = null + ): OrderInterface { + /** @var OrderInterface $order */ + $order = $this->orderFactory->createNew(); + + $order->setCustomer($customer); + $order->setChannel($channel ?? $this->sharedStorage->get('channel')); + $order->setLocaleCode($localeCode ?? $this->sharedStorage->get('locale')->getCode()); + $order->setCurrencyCode($order->getChannel()->getBaseCurrency()->getCode()); + + return $order; + } + + private function createDefaultOrder(): OrderInterface + { + $user = $this->userExampleFactory->create(); + $customer = $user->getCustomer(); + $channel = $this->sharedStorage->get('channel'); + $localeCode = $this->sharedStorage->get('locale')->getCode(); + + /** @var OpenMarketplaceOrderInterface $secondaryOrder */ + $secondaryOrder = $this->createOrder( + $customer, + $number = null, + $channel, + $localeCode + ); + $primaryOrder = $this->createOrder( + $customer, + $number = null, + $channel, + $localeCode + ); + $this->entityManager->persist($primaryOrder); + $secondaryOrder->setPrimaryOrder($primaryOrder); + + return $secondaryOrder; + } + + private function createDefaultVendor(): VendorInterface + { + $user = $this->userExampleFactory->create(['email' => 'test@x.x', 'password' => 'password', 'enabled' => true]); + + $this->sharedStorage->set('user', $user); + + $this->userRepository->add($user); + + $country = $this->entityManager->getRepository(Country::class)->findAll()[0]; + $options = [ + 'company_name' => 'Company Name', + 'phone_number' => '333333333', + 'tax_identifier' => '543455', + 'street' => 'Tajna 13', + 'city' => 'Warsaw', + 'postcode' => '00-111', + 'slug' => 'vendor-slug', + 'description' => 'description', + 'country' => $country, + ]; + /** @var VendorInterface $vendor */ + $vendor = $this->vendorExampleFactory->create($options); + + $vendor->setShopUser($user); + + $this->entityManager->persist($vendor); + $this->entityManager->flush(); + $this->sharedStorage->set('vendor', $vendor); + + return $vendor; + } + + private function applyShipmentTransitionOnOrder(OrderInterface $order, $transition): void + { + foreach ($order->getShipments() as $shipment) { + $this->stateMachineFactory->get($shipment, ShipmentTransitions::GRAPH)->apply($transition); + } + } + + private function createAddress( + CustomerInterface $customer, + CountryInterface $country, + string $city, + string $postalCode, + string $street + ): AddressInterface { + $address = $this->addressFactory->createNew(); + $address->setFirstName($customer->getFirstName()); + $address->setLastName($customer->getLastName()); + $address->setCountryCode($country->getCode()); + $address->setCity($city); + $address->setPostcode($postalCode); + $address->setStreet($street); + + return $address; + } + + /** + * @Given I am on customer details page + */ + public function iAmOnCustomerDetailsPage() + { + $order = $this->sharedStorage->get('order'); + $this->visitPath('/en_US/account/vendor/customers/' . $order->getCustomer()->getId()); + } + + /** + * @Given vendor :vendorEmail has an order with number :number for :price in channel :channelCode + * @Given vendor :vendorEmail has an order with number :number priced at :price in channel :channelCode + */ + public function vendorHasAnOrderWithCodeForInChannel( + string $vendorEmail, + string $number, + string $price, + string $channelCode + ): void { + $price = $this->getPriceFromString($price); + + /** @var ShopUserInterface $shopUser */ + $shopUser = $this->userRepository->findOneBy(['username' => $vendorEmail]); + $channel = $this->entityManager->getRepository(Channel::class)->findOneBy(['name' => $channelCode]); + + /** @var VendorInterface $vendor */ + $vendor = $shopUser->getVendor(); + + /** @var CoreCustomerInterface $customer */ + $customer = $shopUser->getCustomer(); + + $order = $this->orderExampleFactory->createOrderWithTotalAmount( + $channel, + $vendor, + $customer ?? $this->sharedStorage->get('customer'), + $price + ); + + $order->setNumber($number); + + $this->entityManager->persist($order); + $this->entityManager->flush(); + + $this->sharedStorage->set($number, $order); + } + + /** + * @Given order :orderNumber has been paid in current settlement cycle + */ + public function orderHasBeenPaidInCurrentSettlementCycle(string $orderNumber): void + { + $faker = Factory::create(); + $lastSettlement = $this->entityManager->getRepository(SettlementInterface::class)->findOneBy([]); + $order = $this->sharedStorage->get($orderNumber); + + /** @var VendorInterface $vendor */ + $vendor = $order->getVendor(); + Assert::isInstanceOf($vendor, VendorInterface::class); + + [$from, $to] = $this->settlementPeriodResolver->getSettlementDateRangeForVendor( + $vendor, + $vendor->hasCyclicalSettlementFrequency(), + $lastSettlement?->getEndDate() + ); + $paidAt = $faker->dateTimeBetween($from, $to); + $order->setPaidAt($paidAt); + + $this->entityManager->persist($order); + $this->entityManager->flush(); + } + + /** + * @Given order :orderNumber has been paid at the beginning of current settlement cycle + */ + public function orderHasBeenPaidAtTheBeginningOfCurrentSettlementCycle(string $orderNumber): void + { + $lastSettlement = $this->entityManager->getRepository(SettlementInterface::class)->findOneBy([]); + $order = $this->sharedStorage->get($orderNumber); + + /** @var VendorInterface $vendor */ + $vendor = $order->getVendor(); + Assert::isInstanceOf($vendor, VendorInterface::class); + + $frequency = $vendor->getSettlementFrequency(); + + switch ($frequency) { + case VendorSettlementFrequency::MONTHLY: + $modifier = '-1 month'; + + break; + case VendorSettlementFrequency::WEEKLY: + $modifier = '-1 week'; + + break; + case VendorSettlementFrequency::QUARTERLY: + $modifier = '-3 months'; + + break; + default: + $modifier = '-1 day'; + + break; + } + + [$from, $to] = $this->settlementPeriodResolver->getSettlementDateRangeForVendor( + $vendor, + $vendor->hasCyclicalSettlementFrequency(), + $lastSettlement?->getEndDate() + ); + + $from = min($from->modify($modifier), $vendor->getCreatedAt()); + + $order->setPaidAt($from->modify('+1 hour')); + + $this->entityManager->persist($order); + $this->entityManager->flush(); + } + + /** + * @Given order :orderNumber has been included in previously generated settlement + */ + public function orderHasBeenIncludedInPreviouslyGeneratedSettlement(string $orderNumber): void + { + $lastSettlement = $this->entityManager->getRepository(SettlementInterface::class)->findOneBy([]); + $order = $this->sharedStorage->get($orderNumber); + + /** @var VendorInterface $vendor */ + $vendor = $order->getVendor(); + Assert::isInstanceOf($vendor, VendorInterface::class); + + [$from, $to] = $this->settlementPeriodResolver->getSettlementDateRangeForVendor( + $vendor, + $vendor->hasCyclicalSettlementFrequency(), + $lastSettlement?->getEndDate() + ); + $paidAt = $from->modify('-1 day'); + $order->setPaidAt($paidAt); + + $this->settlementCreator->createSettlementsForAutoGeneration( + $vendor, + [$order->getChannel()], + ); + + $this->entityManager->persist($order); + $this->entityManager->flush(); + } + + private function getPriceFromString(string $priceString): int + { + $sign = $priceString[0]; + $price = substr($priceString, 1); + $this->validatePriceString($price); + + $price = (int) round((float) $price * 100, 2); + + if ('-' === $sign) { + $price *= -1; + } + + return $price; + } + + private function validatePriceString(string $price): void + { + if (!preg_match('/^\d+(?:\.\d{1,2})?$/', $price)) { + throw new \InvalidArgumentException('Price string should not have more than 2 decimal digits.'); + } + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Setup/PaymentMethodContext.php b/OpenMarketplace/tests/Behat/Context/Setup/PaymentMethodContext.php new file mode 100644 index 0000000..42a981d --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Setup/PaymentMethodContext.php @@ -0,0 +1,50 @@ +paymentMethodFactory->createNew(); + $paymentMethod->setName($paymentMethodName); + $paymentMethod->setCode($paymentMethodCode); + + $gateway = new GatewayConfig(); + $gateway->setGatewayName('offline'); + $gateway->setFactoryName('offline'); + $gateway->setConfig([]); + + $paymentMethod->addChannel($this->sharedStorage->get('channel')); + $paymentMethod->setGatewayConfig($gateway); + + $this->paymentMethodRepository->add($paymentMethod); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Setup/ProductContext.php b/OpenMarketplace/tests/Behat/Context/Setup/ProductContext.php new file mode 100644 index 0000000..61b973c --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Setup/ProductContext.php @@ -0,0 +1,444 @@ +vendorRepository = $vendorRepository; + $this->productVariantRepository = $productVariantRepository; + $this->productRepository = $productRepository; + $this->userExampleFactory = $userExampleFactory; + $this->entityManager = $entityManager; + $this->productExampleFactory = $productExampleFactory; + $this->taxonFactory = $taxonFactory; + $this->sharedStorage = $sharedStorage; + $this->shippingMethodRepository = $shippingMethodRepository; + $this->slugGenerator = $slugGenerator; + $this->defaultVariantResolver = $defaultVariantResolver; + $this->productFactory = $productFactory; + $this->channelPricingFactory = $channelPricingFactory; + $this->vendorExampleFactory = $vendorExampleFactory; + $this->userRepository = $userRepository; + } + + /** + * @Given store has :productsCount products from same Vendor + */ + public function storeHasProductsFromSameVendor($productsCount): void + { + $this->createTaxon(); + $vendor = $this->createDefaultVendor(null); + for ($i = 1; $i <= $productsCount; ++$i) { + $products[$i] = $this->productExampleFactory->create(); + $products[$i]->setVendor($vendor); + $this->vendorRepository->add($vendor); + $this->productRepository->add($products[$i]); + $this->sharedStorage->set('vendor', $vendor); + $this->sharedStorage->set('products', $products); + } + } + + /** + * @Given store has :productsCount products from vendor :username + */ + public function storeHasProductsFromVendorNamed($productsCount, $username): void + { + $this->createTaxon(); + /** @var ShopUserInterface $user */ + $user = $this->userRepository->findOneBy(['username' => $username]); + $vendor = $user->getVendor(); + for ($i = 1; $i <= $productsCount; ++$i) { + $products[$i] = $this->productExampleFactory->create(); + $products[$i]->setVendor($vendor); + $this->vendorRepository->add($vendor); + $this->productRepository->add($products[$i]); + + $this->sharedStorage->set('products', $products); + } + } + + /** + * @Given store has :productsCount products created by admin + */ + public function storeHasProductsFromAdmin($productsCount): void + { + $this->createTaxon(); + for ($i = 1; $i <= $productsCount; ++$i) { + $products[$i] = $this->productExampleFactory->create(); + $this->productRepository->add($products[$i]); + + $this->sharedStorage->set('products', $products); + } + } + + /** + * @Given store has :productsCount products from different Vendors + * @Given store has :productsCount products from different Vendors with default commission settings + */ + public function storeHasProductsFromDifferentVendors($productsCount) + { + $this->createTaxon(); + for ($i = 1; $i <= $productsCount; ++$i) { + $vendors[$i] = $this->createDefaultVendor($i); + $products[$i] = $this->productExampleFactory->create(); + $products[$i]->setVendor($vendors[$i]); + $this->vendorRepository->add($vendors[$i]); + $this->productRepository->add($products[$i]); + + $this->sharedStorage->set('products', $products); + } + } + + /** + * @Given store has :productsCount products from different Vendors with random commission settings + */ + public function storeHasProductsFromDifferentVendorsWithRandomCommissions($productsCount) + { + $this->createTaxon(); + $commissionTypes = [VendorInterface::NET_COMMISSION, VendorInterface::GROSS_COMMISSION]; + for ($i = 1; $i <= $productsCount; ++$i) { + $vendor = $this->createDefaultVendor($i); + $vendor->setCommission(random_int(1, 10)); + $vendor->setCommissionType($commissionTypes[array_rand($commissionTypes)]); + $vendors[$i] = $vendor; + $products[$i] = $this->productExampleFactory->create(); + $products[$i]->setVendor($vendors[$i]); + $this->vendorRepository->add($vendors[$i]); + $this->productRepository->add($products[$i]); + + $this->sharedStorage->set('products', $products); + } + } + + /** + * @Given store has :vendorsCount vendors with different product each + */ + public function storeHasVendorsWithDifferentProductEach(int $vendorsCount) + { + $name = 'product-'; + $basePrice = 100; + for ($i = 1; $i <= $vendorsCount; ++$i) { + $vendors[$i] = $this->createDefaultVendor($i); + $products[$i] = $this->createProduct(sprintf('%s%d', $name, $i), $vendors[$i], $basePrice * $i); + $this->vendorRepository->add($vendors[$i]); + $this->productRepository->add($products[$i]); + + $this->sharedStorage->set('products', $products); + } + } + + /** + * @Given there is a product :name attached to the product listing + */ + public function thereIsProductsForListing(string $name): void + { + $listing = $this->sharedStorage->get('product_listing'); + Assert::isInstanceOf($listing, ListingInterface::class); + + $product = $this->createProduct( + $name, + $listing->getVendor() + ); + + $listing->setProduct($product); + + $this->sharedStorage->set('product', $product); + + $this->entityManager->persist($product); + $this->entityManager->persist($listing); + + $this->entityManager->flush(); + } + + private function createProduct( + string $productName, + VendorInterface $vendor, + int $price = 100, + string $date = 'now', + ChannelInterface $channel = null + ): \Sylius\Component\Core\Model\ProductInterface { + if (null === $channel && $this->sharedStorage->has('channel')) { + $channel = $this->sharedStorage->get('channel'); + } + + $date = new \DateTime($date); + + /** @var ProductInterface $product */ + $product = $this->productFactory->createWithVariant(); + + $product->setCode(StringInflector::nameToUppercaseCode($productName)); + $product->setName($productName); + $product->setSlug($this->slugGenerator->generate($productName)); + $product->setVendor($vendor); + $product->setCreatedAt($date); + + if (null !== $channel) { + $product->addChannel($channel); + + foreach ($channel->getLocales() as $locale) { + $product->setFallbackLocale($locale->getCode()); + $product->setCurrentLocale($locale->getCode()); + + $product->setName($productName); + $product->setSlug($this->slugGenerator->generate($productName)); + } + } + + /** @var ProductVariantInterface $productVariant */ + $productVariant = $this->defaultVariantResolver->getVariant($product); + + if (null !== $channel) { + $productVariant->addChannelPricing($this->createChannelPricingForChannel($price, $channel)); + } + + $productVariant->setCode($product->getCode()); + $productVariant->setName($product->getName()); + $productVariant->setCreatedAt($date); + $productVariant->setUpdatedAt($date); + + return $product; + } + + private function createChannelPricingForChannel(int $price, ChannelInterface $channel = null) + { + /** @var ChannelPricingInterface $channelPricing */ + $channelPricing = $this->channelPricingFactory->createNew(); + $channelPricing->setPrice($price); + $channelPricing->setChannelCode($channel->getCode()); + + return $channelPricing; + } + + /** + * @Then product on hand count should be :count + */ + public function productOnHoldCountShouldBe(int $count) + { + $product = $this->sharedStorage->get('product'); + + $variant = $this->productVariantRepository->findOneBy(['product' => $product]); + $this->entityManager->refresh($variant); + Assert::same($count, $variant->getOnHand()); + } + + /** + * @Given There is a product with variant code :variant_code owned by logged in vendor + */ + public function thereIsProductWithVariantCodeOwnedByLoggedInVendor($variant_code) + { + $vendor = $this->sharedStorage->get('vendor'); + + $this->createTaxon(); + $product = $this->productExampleFactory->create(); + $product->setVendor($vendor); + $product->getVariants()[0]->setCode($variant_code); + $this->productRepository->add($product); + $this->sharedStorage->set('product', $product); + } + + /** + * @Given one of it belongs to :shippingCategory shipping category + */ + public function oneOfItBelongsToShippingCategory(ShippingCategoryInterface $shippingCategory) + { + $products = $this->sharedStorage->get('products'); + $products[1]->getVariants()->first()->setShippingCategory($shippingCategory); + + $this->entityManager->flush(); + } + + /** + * @Given one of it not belongs to :shippingCategory shipping category + */ + public function oneOfItNotBelongsToShippingCategory(ShippingCategoryInterface $shippingCategory) + { + $products = $this->sharedStorage->get('products'); + $products[1]->getVariants()->first()->setShippingCategory(null); + + $this->entityManager->flush(); + } + + /** + * @Given vendor uses this shipping method + */ + public function vendorUsesThisShippingMethod() + { + /** @var VendorInterface $vendor */ + $vendor = $this->sharedStorage->get('vendor'); + /** @var VendorShippingMethodInterface $shippingMethod */ + $shippingMethod = $this->shippingMethodRepository->findOneBy(['code' => 'ENVELOPE-US']); + $vendorShippingMethod = new VendorShippingMethod(); + $vendorShippingMethod->setVendor($vendor); + $vendorShippingMethod->setShippingMethod($shippingMethod); + $vendorShippingMethod->setChannelCode($this->sharedStorage->get('channel')->getCode()); + $vendor->addShippingMethod($vendorShippingMethod); + $this->entityManager->persist($vendorShippingMethod); + $this->entityManager->persist($vendor); + $this->entityManager->flush(); + } + + /** + * @Given product belongs to :taxonSlug taxon + */ + public function onlyOneProductBelongsToTaxon($taxonSlug) + { + $channel = $this->sharedStorage->get('channel'); + $menuTaxon = $channel->getMenuTaxon(); + /** @var TaxonInterface $taxon */ + $taxon = $this->taxonFactory->create(); + $taxon->setCode('code'); + $taxon->setSlug($taxonSlug); + $taxon->setEnabled(true); + + $taxon->setParent($menuTaxon); + + $products = $this->sharedStorage->get('products'); + + $products[1]->setMainTaxon($taxon); + + $productTaxon = new ProductTaxon(); + $productTaxon->setProduct($products[1]); + $productTaxon->setTaxon($taxon); + + $this->entityManager->persist($productTaxon); + $this->entityManager->persist($products[1]); + $this->entityManager->persist($taxon); + $this->entityManager->flush(); + } + + /** + * @Given product has name :name + */ + public function productHasName($name) + { + $products = $this->sharedStorage->get('products'); + + $products[1]->setName($name); + + $this->entityManager->persist($products[1]); + + $this->entityManager->flush(); + } + + private function createDefaultVendor(?int $iteration): VendorInterface + { + if (1 === $iteration) { + $iteration = null; + } + $userFactory = $this->userExampleFactory; + $user = $userFactory->create(); + + $options = [ + 'company_name' => 'company', + 'phone_number' => '333', + 'tax_identifier' => '111', + 'slug' => 'SLUG' . "$iteration", + 'description' => 'description', + ]; + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorExampleFactory->create($options); + $vendor->setShopUser($user); + + $this->entityManager->persist($user); + + return $vendor; + } + + private function createTaxon() + { + $taxon = $this->taxonFactory->create(); + $channel = $this->sharedStorage->get('channel'); + $channel->setMenuTaxon($taxon); + $this->entityManager->persist($channel); + $this->entityManager->persist($taxon); + $this->entityManager->flush(); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Setup/ProductListingContext.php b/OpenMarketplace/tests/Behat/Context/Setup/ProductListingContext.php new file mode 100644 index 0000000..fdb7c53 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Setup/ProductListingContext.php @@ -0,0 +1,350 @@ +visitPath('/en_US/account/dashboard'); + } + + /** + * @Given I am on a conversations page + */ + public function iAmOnConversationsPage(): void + { + $this->visitPath('/en_US/account/vendor/conversations'); + } + + /** + * @Given I am on an admin dashboard page + */ + public function iAmOnAnAdminDashboardPage(): void + { + $this->visitPath('/admin'); + } + + /** + * @Given There is a verified product listing created by vendor + */ + public function thereIsAVerifiedProductListingCreatedByVendor(): void + { + $vendor = $this->sharedStorage->get('vendor'); + $productListing = $this->createProductListing( + $vendor, + DraftInterface::STATUS_VERIFIED + ); + + $this->entityManager->persist($productListing); + $this->entityManager->flush(); + } + + /** + * @Given There is a rejected product listing created by vendor + */ + public function thereIsARejectedProductListingCreatedByVendor(): void + { + $vendor = $this->sharedStorage->get('vendor'); + $productListing = $this->createProductListing( + $vendor, + DraftInterface::STATUS_REJECTED + ); + + $this->entityManager->persist($productListing); + + /** @var DraftInterface $draft */ + $draft = $productListing->getLatestDraft(); + + $draftViewURL = $this->router->generate( + 'open_marketplace_vendor_product_listings_show', + [ + 'id' => $draft->getId(), + '_locale' => 'en_US', + ], + UrlGenerator::ABSOLUTE_URL + ); + + $category = $this->categoryFactory->createNewWithName( + 'Product listing rejection' + ); + + $this->entityManager->persist($category); + + $conversation = $this->conversationFactory->createNew(); + $conversation->setShopUser($productListing->getVendor()->getShopUser()); + $conversation->setRejectedListingURL($draftViewURL); + $conversation->setCategory($category); + + $message = $this->createMessage( + 'Listing with selected tax category was rejected', + ); + + $conversation->addMessage($message); + + $this->entityManager->persist($conversation); + $this->entityManager->flush(); + } + + /** + * @Given There is an under verification product listing created by vendor + */ + public function thereIsAUnderVerificationProductListingCreatedByVendor(): void + { + $vendor = $this->sharedStorage->get('vendor'); + $productListing = $this->createProductListing( + $vendor, + DraftInterface::STATUS_UNDER_VERIFICATION + ); + + $this->entityManager->persist($productListing); + $this->entityManager->flush(); + } + + private function createProductListing( + VendorInterface $vendor, + string $draftStatus, + ): Listing { + $productListing = new Listing(); + $productListing->setCode('code'); + $productListing->setVendor($vendor); + + $productDraft = $this->createProductDraft($draftStatus); + $productDraft->setProductListing($productListing); + $productListing->insertDraft($productDraft); + + $productTranslation = $this->createProductTranslation($productDraft); + $this->entityManager->persist($productTranslation); + + $productPricing = $this->createProductPricing($productDraft); + $this->entityManager->persist($productPricing); + + return $productListing; + } + + /** + * @Given This product draft has Tax category named :taxCategoryName + */ + public function thisProductDraftHasStatusAccepted(string $taxCategoryName): void + { + /** @var DraftInterface $productDraft */ + $productDraft = $this->entityManager->getRepository(Draft::class) + ->findOneBy(['code' => 'code']); + + /** @var TaxCategory $taxCategory */ + $taxCategory = $this->entityManager->getRepository(TaxCategory::class) + ->findOneBy(['name' => $taxCategoryName]); + + $productDraft->setTaxCategory($taxCategory); + $this->entityManager->persist($productDraft); + $this->entityManager->flush(); + } + + /** + * @Given This product listing has status accepted + */ + public function thisProductListingHasStatusAccepted(): void + { + /** @var DraftInterface $draft */ + $draft = $this->entityManager->getRepository(Draft::class)->findOneBy(['code' => 'code']); + $newProduct = $this->acceptanceOperator->convertToSimpleProduct($draft); + $draft->setStatus('verified'); + $this->entityManager->persist($newProduct); + $this->entityManager->flush(); + } + + /** + * @Then I click button with id :id + */ + public function iClickButton(string $id): void + { + $page = $this->getSession()->getPage(); + $button = $page->find('css', '#' . $id); + $button->press(); + } + + /** + * @Then I should be notified no page exits + */ + public function iShouldBeNotifiedNoPageExits(): void + { + $status = $this->getSession()->getStatusCode(); + Assert::eq($status, 404); + } + + /** + * @Then I fill in conversation message content with :message + */ + public function iFillInConversationMessageContentWithMessage( + string $message + ): void { + $this->showAdminPage->fillRejectMessage($message); + } + + /** + * @Then I fill in Tax category with :taxCategory + */ + public function iFillInTaxCategoryWithTaxCategory( + string $taxCategoryName, + ): void { + $this->productListingCreateVendorPage->fillTaxCategory($taxCategoryName); + } + + /** + * @Given there is tax category :taxCategoryName with code :code + */ + public function thereIsTaxCategoryWithCode( + string $taxCategoryName, + string $code, + ): void { + /** @var TaxCategoryInterface $taxCategory */ + $taxCategory = $this->taxCategoryExampleFactory->createNew(); + $taxCategory->setName($taxCategoryName); + $taxCategory->setCode($code); + + $this->entityManager->persist($taxCategory); + $this->entityManager->flush(); + } + + /** + * @Given I should see taxCategory :taxCategoryName for product listing + */ + public function iShouldSeeTaxCategoryForProductListing( + string $taxCategoryName + ): void { + $productListingTaxCategory = $this->getPage() + ->find( + 'css', + sprintf( + 'table > tbody > tr > td:contains("%s")', + $taxCategoryName, + ), + ); + Assert::notNull($productListingTaxCategory); + } + + /** + * @return DocumentElement + */ + private function getPage() + { + return $this->getSession()->getPage(); + } + + private function createProductDraft( + string $status + ): DraftInterface { + $productDraft = new Draft(); + $productDraft->setCode('code'); + $productDraft->setStatus($status); + $productDraft->setPublishedAt(new \DateTime()); + $productDraft->setVersionNumber(0); + + return $productDraft; + } + + private function createProductTranslation( + DraftInterface $productDraft + ): DraftTranslationInterface { + $productTranslation = new DraftTranslation(); + $productTranslation->setLocale('en_US'); + $productTranslation->setSlug('product-listing-slug'); + $productTranslation->setName('ProductListingName'); + $productTranslation->setDescription('product-listing-'); + $productTranslation->setProductDraft($productDraft); + + return $productTranslation; + } + + private function createProductPricing( + DraftInterface $productDraft + ): ListingPriceInterface { + $productPricing = new ListingPrice(); + $productPricing->setProductDraft($productDraft); + $productPricing->setPrice(1000); + $productPricing->setOriginalPrice(1000); + $productPricing->setMinimumPrice(1000); + $productPricing->setChannelCode('en_US'); + + return $productPricing; + } + + private function createMessage( + string $content, + ): MessageInterface { + /** @var MessageInterface $message */ + $message = $this->messageFactory->createNew(); + + $user = $this->userContext->getUser(); + + if ($user instanceof AdminUserInterface) { + $message->setAdminUser($user); + } + + if ($user instanceof ShopUserInterface) { + $message->setShopUser($user); + $message->setAuthor($user); + } + + $message->setContent($content); + + return $message; + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Setup/SettlementContext.php b/OpenMarketplace/tests/Behat/Context/Setup/SettlementContext.php new file mode 100644 index 0000000..fd637b9 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Setup/SettlementContext.php @@ -0,0 +1,101 @@ +sharedStorage->get('vendor'); + + $settlement = $this->settlementExampleFactory->create([ + 'status' => $status, + 'totalAmount' => (int) floor($totalAmount * 100), + 'totalCommissionAmount' => (int) floor($commissionTotalAmount * 100), + 'vendor' => $vendor, + ]); + + $this->entityManager->persist($settlement); + $this->entityManager->flush(); + } + + /** + * @Given there is a settlement with period from :from to :to + */ + public function thereIsASettlementWithPeriodFromTo( + string $from, + string $to, + ): void { + $vendor = $this->sharedStorage->get('vendor'); + + $settlement = $this->settlementExampleFactory->create([ + 'vendor' => $vendor, + 'startDate' => \DateTime::createFromFormat('d/m/Y H:i:s', sprintf('%s 00:00:00', $from)), + 'endDate' => \DateTime::createFromFormat('d/m/Y H:i:s', sprintf('%s 23:59:59', $to)), + ]); + + $this->entityManager->persist($settlement); + $this->entityManager->flush(); + } + + /** + * @Given there is a :status settlement for vendor :vendorEmail + */ + public function thereIsASettlementForVendor( + string $status, + string $vendorEmail, + ): void { + $settlement = $this->settlementExampleFactory->create([ + 'status' => $status, + 'vendor' => $vendorEmail, + ]); + + $this->entityManager->persist($settlement); + $this->entityManager->flush(); + } + + /** + * @Given there is a settlement for channel :channelName + */ + public function thereIsASettlementForChannel(string $channelName): void + { + $vendor = $this->sharedStorage->get('vendor'); + + $settlement = $this->settlementExampleFactory->create([ + 'vendor' => $vendor, + 'channel' => StringInflector::nameToLowercaseCode($channelName), + ]); + + $this->entityManager->persist($settlement); + $this->entityManager->flush(); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Setup/VendorContext.php b/OpenMarketplace/tests/Behat/Context/Setup/VendorContext.php new file mode 100644 index 0000000..16ae2cc --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Setup/VendorContext.php @@ -0,0 +1,154 @@ +shopUserExampleFactory->create(['email' => $vendorUserEmail, 'password' => 'password', 'enabled' => true]); + $user->setVerifiedAt(new \DateTime()); + $user->addRole('ROLE_USER'); + $user->addRole('ROLE_VENDOR'); + + $this->sharedStorage->set('user', $user); + + $this->entityManager->persist($user); + + $country = $this->entityManager->getRepository(Country::class)->findOneBy(['code' => $countryCode]); + if (null === $country) { + /** @var CountryInterface $country */ + $country = $this->countryFactory->createNew(); + $country->setCode($countryCode); + $country->enable(); + $this->entityManager->persist($country); + } + + $options = [ + 'company_name' => $name ?? 'Test', + 'phone_number' => '333333333', + 'tax_identifier' => '543455', + 'bank_account_number' => 'NL31INGB4405427607', + 'street' => 'Secret 13', + 'city' => 'Warsaw', + 'postcode' => '00-111', + 'slug' => 'vendor-slug', + 'description' => 'description', + 'country' => $country, + 'status' => $status, + ]; + + $vendor = $this->vendorExampleFactory->create($options); + $vendor->setShopUser($user); + $this->entityManager->persist($vendor); + $this->entityManager->flush(); + $this->sharedStorage->set('vendor', $vendor); + } + + /** + * @Given there is an vendor user :username with password :password + */ + public function thereIsAnVendorUserWithPassword(string $username, string $password): void + { + /** @var ShopUserInterface $user */ + $user = $this->shopUserExampleFactory->create(); + $user->setUsername($username); + $user->setPlainPassword($password); + $user->setEmail($username . '@email.com'); + $this->entityManager->persist($user); + + $options = [ + 'company_name' => 'vendor', + 'phone_number' => '987654321', + 'tax_identifier' => '123456789', + 'slug' => 'vendor-slug', + 'description' => 'description', + ]; + + /** @var Vendor $vendor */ + $vendor = $this->vendorExampleFactory->create($options); + + $vendor->setShopUser($user); + $this->entityManager->persist($vendor); + + $this->entityManager->flush(); + + $this->sharedStorage->set('vendor', $vendor); + } + + /** + * @Given vendor :vendorEmail has :frequency settlement frequency + */ + public function vendorHasSettlementFrequency(string $vendorEmail, string $frequency): void + { + $frequency = StringInflector::nameToLowercaseCode($frequency); + Assert::inArray($frequency, VendorSettlementFrequency::SETTLEMENT_FREQUENCIES); + $vendor = $this->getVendorByEmail($vendorEmail); + $vendor->setSettlementFrequency($frequency); + $this->entityManager->persist($vendor); + $this->entityManager->flush(); + } + + /** + * @Given vendor :vendorEmail was created on :dateTimeString + */ + public function vendorWasCreatedOn(string $vendorEmail, string $dateTimeString): void + { + $vendor = $this->getVendorByEmail($vendorEmail); + $vendor->setCreatedAt(new \DateTime($dateTimeString)); + + $this->entityManager->persist($vendor); + $this->entityManager->flush(); + } + + private function getVendorByEmail(string $vendorEmail): VendorInterface + { + $shopUser = $this->entityManager->getRepository(ShopUserInterface::class)->findOneBy(['username' => $vendorEmail]); + $vendor = $shopUser->getVendor(); + Assert::isInstanceOf($vendor, VendorInterface::class); + + return $vendor; + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Setup/VirtualWalletContext.php b/OpenMarketplace/tests/Behat/Context/Setup/VirtualWalletContext.php new file mode 100644 index 0000000..0d5f267 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Setup/VirtualWalletContext.php @@ -0,0 +1,116 @@ +getVendorByEmail($vendorEmail); + $channel = $this->entityManager->getRepository(Channel::class)->findOneBy(['name' => $channelName]); + + $virtualWallet = $this->virtualWalletFactory->createVirtualWalletWithBalance( + $channel, + $vendor, + $this->getCustomer($vendor), + (int) floor($balance * 100), + ); + + $this->entityManager->persist($virtualWallet); + $this->entityManager->flush(); + } + + /** + * @Given there is a virtual wallet for channel :channelName with balance :balance + */ + public function thereIsAVirtualWalletForChannelAndBalance(string $channelName, float $balance): void + { + $channel = $this->entityManager->getRepository(Channel::class)->findOneBy(['name' => $channelName]); + $vendor = $this->sharedStorage->get('vendor'); + + $virtualWallet = $this->virtualWalletFactory->createVirtualWalletWithBalance( + $channel, + $vendor, + $this->getCustomer($vendor), + (int) floor($balance * 100), + ); + + $this->entityManager->persist($virtualWallet); + $this->entityManager->flush(); + } + + /** + * @Given there is a virtual wallet for vendor :vendorEmail with balance :balance + */ + public function thereIsAVirtualWalletForVendorAndBalance(string $channelName, float $balance): void + { + $vendor = $this->entityManager->getRepository(Vendor::class)->findOneBy(['email' => $vendorEmail]); + $channel = $this->sharedStorage->get('channel'); + + $virtualWallet = $this->virtualWalletFactory->createVirtualWalletWithBalance( + $vendor, + $channel, + $this->getCustomer($vendor), + (int) floor($balance * 100), + ); + + $this->entityManager->persist($virtualWallet); + $this->entityManager->flush(); + } + + private function getVendorByEmail(string $vendorEmail): VendorInterface + { + $shopUser = $this->entityManager->getRepository(ShopUser::class)->findOneBy(['username' => $vendorEmail]); + Assert::isInstanceOf($shopUser, ShopUser::class); + + $vendor = $shopUser->getVendor(); + Assert::isInstanceOf($vendor, VendorInterface::class); + + return $vendor; + } + + private function getCustomer(VendorInterface $vendor): CustomerInterface + { + $shopUser = $vendor->getShopUser(); + Assert::isInstanceOf($shopUser, ShopUser::class); + + $customer = $shopUser->getCustomer(); + + return ($customer instanceof CustomerInterface) + ? $customer + : $this->sharedStorage->get('customer'); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Shop/OrderContext.php b/OpenMarketplace/tests/Behat/Context/Shop/OrderContext.php new file mode 100644 index 0000000..58c1a3e --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Shop/OrderContext.php @@ -0,0 +1,388 @@ +productPage = $productPage; + $this->sharedStorage = $sharedStorage; + $this->orderRepository = $orderRepository; + $this->paymentMethodFactory = $paymentMethodFactory; + $this->methodRepository = $methodRepository; + } + + /** + * @Then I should see :count orders + */ + public function iShouldSeeOrders($count) + { + $page = $this->getSession()->getPage(); + $tableWrapper = $page->find('css', 'table'); + $orders = $tableWrapper->findAll('css', '.item'); + Assert::eq(count($orders), $count); + } + + /** + * @Then I should see :count :mode order(s) + */ + public function iShouldSeeOrdersWithMode($count, $mode) + { + $page = $this->getSession()->getPage(); + $tableWrapper = $page->find('css', 'table'); + $orders = $tableWrapper->findAll('css', '.item'); + Assert::eq(count($orders), $count); + $htmlString = $page->getHtml(); + $pattern = "/\/admin\/orders\/(\d+)/"; + preg_match_all($pattern, $htmlString, $matches); + $orders = $this->orderRepository->findBy(['id' => $matches[1]]); + Assert::eq(count($orders), $count); + foreach ($orders as $order) { + Assert::eq($order->getMode(), $mode); + } + } + + /** + * @Then I should see :count :mode order(s) in order history + */ + public function iShouldSeeOrdersWithModeInHistory($count, $mode) + { + $page = $this->getSession()->getPage(); + $tableWrapper = $page->find('css', 'table'); + $orders = $tableWrapper->findAll('css', '.item'); + Assert::eq(count($orders), $count); + $htmlString = $page->getHtml(); + $pattern = "/\/.*\/account\/orders\/(\d+)/"; + preg_match_all($pattern, $htmlString, $matches); + $orders = $this->orderRepository->findBy(['number' => $matches[1]]); + Assert::eq(count($orders), $count); + foreach ($orders as $order) { + Assert::eq($order->getMode(), $mode); + } + } + + /** + * @Then I should see :count orders with :status status label :color + */ + public function iShouldSeeOrdersWithStatus( + int $count, + string $status, + string $color + ) { + $page = $this->getSession()->getPage(); + $tableWrapper = $page->find('css', 'table'); + $orders = $tableWrapper->findAll('css', '.item'); + Assert::eq(count($orders), $count); + $labels = $page->findAll('css', '.ui.' . $color . 'label'); + foreach ($labels as $label) { + Assert::eq($label->getText(), $status); + } + } + + /** + * @Given I complete checkout + */ + public function iCompleteCheckout() + { + $page = $this->getSession()->getPage(); + $page->find('css', 'button')->press(); + } + + /** + * @Given I submit form + */ + public function iSubmitForm() + { + $page = $this->getSession()->getPage(); + $page->find('css', '.ui.large.primary.icon.labeled.button')->press(); + } + + /** + * @Given I choose shipment + */ + public function iChooseShipment() + { + $page = $this->getSession()->getPage(); + $page->find('css', '.ui.large.primary.icon.labeled.button')->press(); + } + + /** + * @Given I choose payment + */ + public function iChoosePayment() + { + $page = $this->getSession()->getPage(); + $page->find('css', '.ui.large.primary.icon.labeled.button')->press(); + } + + /** + * @Given I choose payment method by code :code + */ + public function iChoosePaymentMethodByCode(string $code): void + { + $page = $this->getSession()->getPage(); + + $radioButton = $page->find('css', "input[type='radio']"); + + if (null === $radioButton) { + throw new \InvalidArgumentException(sprintf('Could not find payment method with code "%s".', $code)); + } + + $radioButton->selectOption($code); + $page->find('css', '.ui.large.primary.icon.labeled.button')->press(); + } + + /** + * @Given I have :count products in cart + */ + public function iHaveProductsInCart($count) + { + $products = $this->sharedStorage->get('products'); + for ($i = 1; $i <= $count; ++$i) { + $slug = $products[$i]->getSlug(); + $this->productPage->open(['slug' => $slug]); + $this->productPage->addToCart(); + } + $this->sharedStorage->set('products', $products); + } + + /** + * @Given I have product :name in cart + */ + public function iHaveProductInCart(string $name) + { + $product = $this->sharedStorage->get('product'); + $slug = $product->getSlug(); + $this->productPage->open(['slug' => $slug]); + $this->productPage->addToCart(); + } + + /** + * @Given I click :button + */ + public function iClickButton($button) + { + $this->getSession()->getPage()->pressButton($button); + } + + /** + * @Then I should see :ordersCount orders on page :pageNumber + */ + public function iShouldSeeOrdersOnPage($ordersCount, $pageNumber) + { + $paginationLimit = $this->sharedStorage->get('pagination_limit'); + $this->visitPath("/en_US/account/vendor/orders?limit=$paginationLimit&page=$pageNumber"); + $page = $this->getSession()->getPage(); + $table = $page->find('css', '.ui.sortable.stackable.very.basic.celled.table'); + $orderRows = $table->findAll('css', '.item'); + + Assert::count($orderRows, $ordersCount); + } + + /** + * @Given Pagination is set to display :paginationLimit orders per page + */ + public function paginationIsSetToDisplayOrderPerPage($paginationLimit) + { + $this->sharedStorage->set('pagination_limit', $paginationLimit); + } + + /** + * @Then I should see customer with name :name + */ + public function iShouldSeeClientWithName($name) + { + $page = $this->getSession()->getPage(); + $table = $page->find('css', '.ui.sortable.stackable.very.basic.celled.table'); + assertStringContainsString($name, $table->getText()); + } + + /** + * @Then I should not see customer with name :name + */ + public function iShouldNotSeeClientWithName($name) + { + $page = $this->getSession()->getPage(); + assertStringNotContainsString($name, $page->getText()); + } + + /** + * @Given I am on customers page + */ + public function iAmOnCustomersPage() + { + $this->visitPath('en_US/account/vendor/customers'); + } + + /** + * @Then I should see customer details with name :name + */ + public function iShouldSeeCustomerDetailsWithName($name) + { + $page = $this->getSession()->getPage(); + $card = $page->find('css', '.ui.fluid.card'); + assertStringContainsString($name, $card->getText()); + } + + /** + * @Given I add this product to the cart + */ + public function iAddThisProductToTheCart() + { + $product = $this->sharedStorage->get('product'); + + $slug = $product->getSlug(); + $this->productPage->open(['slug' => $slug]); + $this->productPage->addToCart(); + + $this->sharedStorage->set('product', $product); + } + + /** + * @Given I finalize order + */ + public function iFinalizeOrder() + { + $this->iProvideAddressInformation(); + $this->iChooseShipment(); + $this->iChoosePayment(); + $this->iCompleteCheckout(); + } + + /** + * @Given I finalize order with payment method :code + */ + public function iFinalizeOrderWithPaymentMethodCode(string $code) + { + $this->iProvideAddressInformation(); + $this->iChooseShipment(); + $this->iChoosePaymentMethodByCode($code); + $this->iCompleteCheckout(); + } + + /** + * @Given I provide address information + */ + public function iProvideAddressInformation(): void + { + $this->visitPath('/en_US/checkout/address'); + $this->fillField('sylius_checkout_address[billingAddress][firstName]', 'Test name'); + $this->fillField('sylius_checkout_address[billingAddress][lastName]', 'Test name'); + $this->fillField('sylius_checkout_address[billingAddress][company]', 'Test company'); + $this->fillField('sylius_checkout_address[billingAddress][street]', 'Test street'); + $this->selectOption('sylius_checkout_address[billingAddress][countryCode]', 'United States'); + $this->fillField('sylius_checkout_address[billingAddress][city]', 'Test city'); + $this->fillField('sylius_checkout_address[billingAddress][postcode]', 'Test code'); + $this->iSubmitForm(); + } + + /** + * @Then primary order should not have number + */ + public function primaryOrderShouldNotHaveNumber() + { + /** @var Order|null $order */ + $order = $this->orderRepository->findOneBy(['mode' => OrderInterface::PRIMARY_ORDER_MODE]); + + if (null !== $order) { + Assert::eq($order->getNumber(), null); + } + } + + private function fillField($field, $value) + { + $field = $this->fixStepArgument($field); + $value = $this->fixStepArgument($value); + $this->getSession()->getPage()->fillField($field, $value); + } + + private function fixStepArgument($argument): array|string + { + return str_replace('\\"', '"', $argument); + } + + private function selectOption($select, $option): void + { + $select = $this->fixStepArgument($select); + $option = $this->fixStepArgument($option); + $this->getSession()->getPage()->selectFieldOption($select, $option); + } + + private function getPage(): DocumentElement + { + return $this->getSession()->getPage(); + } + + /** + * @Given There is payment method + */ + public function thereIsPaymentMethod(): void + { + $payment = $this->paymentMethodFactory->create([ + 'name' => ucfirst($name), + 'code' => $code, + 'description' => $description, + 'gatewayName' => $gatewayFactory, + 'gatewayFactory' => $gatewayFactory, + 'enabled' => true, + 'channels' => ($addForCurrentChannel && $this->sharedStorage->has('channel')) ? [$this->sharedStorage->get('channel')] : [], + ]); + $this->methodRepository->add($payment); + } + + /** + * @Then I should see :name payment method + */ + public function iShouldSeePaymentMethod(string $name): void + { + $this->assertSession()->pageTextContains($this->fixStepArgument($name)); + } + + /** + * @Then I follow :label button + */ + public function iFollowButton(string $label): void + { + $label = $this->fixStepArgument($label); + $this->getSession()->getPage()->clickLink($label); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Ui/Admin/AdminContext.php b/OpenMarketplace/tests/Behat/Context/Ui/Admin/AdminContext.php new file mode 100644 index 0000000..444d700 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Ui/Admin/AdminContext.php @@ -0,0 +1,35 @@ +visitPath('/admin/login'); + $page = $this->getPage(); + $page->fillField('Username', 'admin'); + $page->fillField('Password', 'admin'); + $page->pressButton('Login'); + } + + private function getPage(): DocumentElement + { + return $this->getSession()->getPage(); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Ui/Admin/DashboardStatisticsContext.php b/OpenMarketplace/tests/Behat/Context/Ui/Admin/DashboardStatisticsContext.php new file mode 100644 index 0000000..62a9392 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Ui/Admin/DashboardStatisticsContext.php @@ -0,0 +1,36 @@ +entityManager = $entityManager; + } + + /** + * @BeforeScenario + */ + public function clearData() + { + $purger = new ORMPurger($this->entityManager); + $purger->purge(); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Ui/Admin/OrderContext.php b/OpenMarketplace/tests/Behat/Context/Ui/Admin/OrderContext.php new file mode 100644 index 0000000..45f8df9 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Ui/Admin/OrderContext.php @@ -0,0 +1,18 @@ +adminUserExampleFactory->create(); + $admin->setUsername($username); + $admin->setPlainPassword($password); + $admin->setEmail('admin@email.com'); + $this->entityManager->persist($admin); + $this->entityManager->flush(); + + $admin->setPlainPassword($password); + $this->sharedStorage->set('admin', $admin); + } + + /** + * @Given I am logged in as an admin + */ + public function iAmLoggedInAsAnAdmin() + { + $admin = $this->sharedStorage->get('admin'); + + $this->visitPath('/admin/login'); + $this->getPage()->fillField('Username', $admin->getUsername()); + $this->getPage()->fillField('Password', $admin->getPlainPassword()); + $this->getPage()->pressButton('Login'); + ($this->getPage()->findLink('Logout')); + } + + /** + * @Given I am logged in as an user :email with password :password + */ + public function iAmLoggedInAsUserWithPassword(string $email, string $password) + { + $this->visitPath('/en_US/login'); + $this->getPage()->fillField('Username', $email); + $this->getPage()->fillField('Password', $password); + $this->getPage()->pressButton('Login'); + } + + /** + * @Given there is a vendor user :vendor_user_email registered in country :country_code + */ + public function thereIsAVendorUserRegisteredInCountry($vendor_user_email, $country_code): void + { + $user = $this->shopUserExampleFactory->create(['email' => $vendor_user_email, 'password' => 'password', 'enabled' => true]); + + $this->sharedStorage->set('user', $user); + + $this->userRepository->add($user); + + $country = $this->entityManager->getRepository(Country::class)->findOneBy(['code' => $country_code]); + + if (null === $country) { + /** @var CountryInterface $country */ + $country = $this->countryFactory->createNew(); + $country->setCode($country_code); + $country->enable(); + $this->entityManager->persist($country); + } + + $options = [ + 'company_name' => 'Company Name', + 'phone_number' => '333333333', + 'tax_identifier' => '543455', + 'street' => 'Tajna 13', + 'city' => 'Warsaw', + 'postcode' => '00-111', + 'slug' => 'vendor-slug', + 'description' => 'description', + 'country' => $country, + ]; + + $vendor = $this->vendorExampleFactory->create($options); + + $vendor->getVendorAddress()->setCountry($country); + $vendor->setShopUser($user); + + $this->entityManager->persist($vendor); + $this->entityManager->flush(); + $this->sharedStorage->set('vendor', $vendor); + } + + /** + * @Given there is :arg2 product listing created by vendor + */ + public function thereIsProductListingCreatedByVendor($count) + { + $vendor = $this->sharedStorage->get('vendor'); + + for ($i = 0; $i < $count; ++$i) { + $productListing = new Listing(); + $productListing->setCode('code' . $i); + $productListing->setVendor($vendor); + + $productDraft = new Draft(); + $productDraft->setCode('code' . $i); + $productDraft->setVersionNumber(0); + $productDraft->setProductListing($productListing); + $productListing->sendToVerification($productDraft); + + $productTranslation = new DraftTranslation(); + $productTranslation->setLocale('en_US'); + $productTranslation->setSlug('product-listing-' . $i); + $productTranslation->setName('product-listing-' . $i); + $productTranslation->setDescription('product-listing-' . $i); + $productTranslation->setProductDraft($productDraft); + + $productPricing = new ListingPrice(); + $productPricing->setProductDraft($productDraft); + $productPricing->setPrice(1000); + $productPricing->setOriginalPrice(1000); + $productPricing->setMinimumPrice(1000); + $productPricing->setChannelCode('web_us'); + + $this->entityManager->persist($productListing); + $this->entityManager->persist($productDraft); + $this->entityManager->persist($productTranslation); + $this->entityManager->persist($productPricing); + + $this->sharedStorage->set('product_listing' . $i, $productListing); + } + + $this->entityManager->flush(); + } + + /** + * @Given there is/are :count product listing(s) + */ + public function thereAreProductListings($count) + { + $vendor = $this->sharedStorage->get('vendor'); + + for ($i = 0; $i < $count; ++$i) { + $productListing = $this->createProductListing($vendor, 'code' . $i); + $productDraft = $this->createProductListingDraft($productListing, 'code' . $i); + $productTranslation = $this->createProductListingTranslation( + $productDraft, + 'product-listing-' . $i, + 'product-listing-' . $i, + 'product-listing-' . $i + ); + $productPricing = $this->createProductListingPricing($productDraft); + + $productListing->setPublishedAt($productDraft->getPublishedAt()); + $productListing->setVerificationStatus($productDraft->getStatus()); + + $this->entityManager->persist($productListing); + $this->entityManager->persist($productDraft); + $this->entityManager->persist($productTranslation); + $this->entityManager->persist($productPricing); + } + $this->entityManager->flush(); + } + + /** + * @Given there is product listing enabled for channel + */ + public function thereIsProductListingForChannel() + { + $vendor = $this->sharedStorage->get('vendor'); + $channel = $this->getChannel(); + + $productListing = $this->createProductListing($vendor, 'code'); + $productDraft = $this->createProductListingDraft($productListing, 'code'); + $productDraft->addChannel($channel); + $productTranslation = $this->createProductListingTranslation( + $productDraft, + 'product-listing-', + 'product-listing-', + 'product-listing-' + ); + $productPricing = $this->createProductListingPricing($productDraft); + + $productListing->insertDraft($productDraft); + $productListing->setPublishedAt($productDraft->getPublishedAt()); + $productListing->setVerificationStatus($productDraft->getStatus()); + + $this->sharedStorage->set('product_listing', $productListing); + + $this->entityManager->persist($productListing); + $this->entityManager->persist($productDraft); + $this->entityManager->persist($productTranslation); + $this->entityManager->persist($productPricing); + + $this->entityManager->flush(); + } + + /** + * @Then there should be product with channel enabled + */ + public function thereShouldBeProductWithChannel() + { + $setChannel = $this->getChannel(); + $products = $this->entityManager->getRepository(Product::class)->findAll(); + Assert::count($products, 1); + /** @var ProductInterface $product */ + $product = $products[0]; + Assert::count($product->getChannels(), 1); + $productChannels = $product->getChannels(); + /** @var ChannelInterface $productChannel */ + $productChannel = $productChannels[0]; + Assert::eq($setChannel, $productChannel); + } + + /** + * @Given there is a product listing with code :code and name :name and status :status + */ + public function thereIsAProductListingWithCodeAndNameAndStatus( + string $code, + string $name, + string $status + ) { + $vendor = $this->sharedStorage->get('vendor'); + + $productListing = $this->createProductListing($vendor, $code); + $productDraft = $this->createProductListingDraft($productListing, $code, $status); + $productTranslation = $this->createProductListingTranslation($productDraft, $name); + $productPricing = $this->createProductListingPricing($productDraft); + + $this->entityManager->persist($productListing); + $this->entityManager->persist($productDraft); + $this->entityManager->persist($productTranslation); + $this->entityManager->persist($productPricing); + $this->entityManager->flush(); + } + + /** + * @Then I should see :count product listing(s) + */ + public function iShouldSeeProductListings($count) + { + $rows = $this->getPage()->findAll('css', 'table > tbody > tr'); + Assert::notEmpty($rows, 'Could not find any rows'); + Assert::eq($count, count($rows), 'Rows numbers are not equal'); + } + + /** + * @Then I should see url :url + */ + public function iShouldSeeUrl($url) + { + $currentUrl = $this->getSession()->getCurrentUrl(); + $matches = preg_match($url, $currentUrl); + Assert::eq(1, $matches); + } + + /** + * @Given I should see product's listing status :status + */ + public function iShouldSeeProductsListingStatus($status) + { + $productListingStatus = $this->getPage()->find('css', sprintf('table > tbody > tr > td:contains("%s")', $status)); + Assert::notNull($productListingStatus); + } + + /** + * @Given I click :button button + */ + public function iClickButton($button) + { + $this->getPage()->pressButton($button); + } + + /** + * @Then I should be redirected to :url + */ + public function iShouldBeRedirectedTo($url) + { + Assert::eq($url, $this->getSession()->getCurrentUrl()); + } + + /** + * @Given There is attribute with code :code + */ + public function thereIsAttributeWithCode($code): void + { + $vendor = $this->sharedStorage->get('vendor'); + + /** @var DraftAttribute $attribute */ + $attribute = $this->draftAttributeFactory->createNew(); + $attribute->setType('text'); + $attribute->setStorageType('text'); + $attribute->setCode($code); + $attribute->setVendor($vendor); + + $translation = new DraftAttributeTranslation(); + $translation->setLocale('en_US'); + $translation->setTranslatable($attribute); + $translation->setName('attribute'); + + $attribute->addTranslation($translation); + $this->sharedStorage->set('attribute', $attribute); + + $this->entityManager->persist($attribute); + } + + /** + * @Given there is a product listing with code :code and name :name and status :status with attribute and image + */ + public function thereIsAProductListingWithCodeAndNameAndStatusWithAttributeAndImage( + $code, + $name, + $status + ): void { + $vendor = $this->sharedStorage->get('vendor'); + + $attribute = $this->sharedStorage->get('attribute'); + + $attributeValue = new DraftAttributeValue(); + $attributeValue->setAttribute($attribute); + $attributeValue->setLocaleCode('en_US'); + $attributeValue->setValue('attribute_testing_value'); + + $productListing = $this->createProductListing($vendor, $code); + /** @var DraftInterface $productDraft */ + $productDraft = $this->createProductListingDraft($productListing, $code, $status); + $productDraft->addAttribute($attributeValue); + $productTranslation = $this->createProductListingTranslation($productDraft, $name); + + $productPricing = $this->createProductListingPricing($productDraft); + + $draftImage = new DraftImage(); + $draftImage->setOwner($productDraft); + $draftImage->setPath('path/to/file'); + + $productDraft->addImage($draftImage); + + $this->entityManager->persist($productListing); + $this->entityManager->persist($productDraft); + $this->entityManager->persist($productTranslation); + $this->entityManager->persist($productPricing); + $this->entityManager->persist($attributeValue); + $this->entityManager->persist($draftImage); + + $this->entityManager->flush(); + } + + /** + * @When I click :buttonText + */ + public function iClick($buttonText): void + { + $this->getPage()->pressButton($buttonText); + } + + /** + * @Then I should see image + */ + public function iShouldSeeImage(): void + { + $page = $this->getSession()->getPage(); + + $mediaContainer = $page->find('css', '#media'); + $image = $mediaContainer->find('css', 'img'); + $imagePath = $image->getAttribute('src'); + + Assert::contains($imagePath, 'path/to/file', 'no image found'); + } + + /** + * @Given product listing has attribute :code with value :value + */ + public function productListingHasAttributeWithValue(string $code, string $value): void + { + $productListing = $this->sharedStorage->get('product_listing'); + Assert::isInstanceOf($productListing, ListingInterface::class); + + $attribute = $this->sharedStorage->get(sprintf('draft_attribute_%s', $code)); + Assert::isInstanceOf($attribute, DraftAttributeInterface::class); + + $attributeValue = new DraftAttributeValue(); + + $attributeValue->setAttribute($attribute); + $attributeValue->setLocaleCode('en_US'); + $attributeValue->setValue($value); + + $latestDraft = $productListing->getLatestDraft(); + $latestDraft->addAttribute($attributeValue); + + $this->entityManager->persist($latestDraft); + $this->entityManager->persist($productListing); + $this->entityManager->persist($attributeValue); + $this->entityManager->flush(); + } + + /** + * @Given there is already published product with attribute :string with value :value + */ + public function thereIsAlreadyPublishedProductWithAttributeWithValue( + string $code, + string $value + ): void { + $productListing = $this->sharedStorage->get('product_listing'); + Assert::isInstanceOf($productListing, ListingInterface::class); + + $attribute = $this->sharedStorage->get(sprintf('draft_attribute_%s', $code)); + Assert::isInstanceOf($attribute, DraftAttributeInterface::class); + + $product = $this->sharedStorage->get('product'); + Assert::isInstanceOf($product, ProductInterface::class); + $productListing->setProduct($product); + + $productAttribute = $this->productAttributeFactory->createClone($attribute); + + $productAttributeValue = $this->productAttributeValueFactory->createWithProductAttributeAndValue( + $productAttribute, + $value + ); + + $product->addAttribute($productAttributeValue); + + $this->entityManager->persist($productListing); + $this->entityManager->persist($productAttribute); + $this->entityManager->persist($productAttributeValue); + $this->entityManager->persist($product); + + $this->entityManager->flush(); + } + + /** + * @When I should see :attribute with value :value + */ + public function iShouldSeeWithValue(string $attribute, string $value) + { + $page = $this->getPage(); + + $element = $page->find('css', 'div#attributes'); + $attribFound = $element->find('css', sprintf('table > tbody > tr > td:contains("%s")', $value)); + + Assert::notNull($attribFound); + } + + /** + * @When I should not see :attribute with value :value + */ + public function iShouldNotSeeWithValue(string $attribute, string $value): void + { + $page = $this->getPage(); + + $element = $page->find('css', 'div#attributes'); + $foundAttribute = $element->find('css', sprintf('table > tbody > tr > td:contains("%s")', $value)); + + Assert::null($foundAttribute); + } + + /** + * @return DocumentElement + */ + private function getPage() + { + return $this->getSession()->getPage(); + } + + private function createProductListing(VendorInterface $vendor, string $code): ListingInterface + { + $productListing = new Listing(); + $productListing->setCode($code); + $productListing->setVendor($vendor); + + return $productListing; + } + + private function createProductListingDraft( + ListingInterface $productListing, + string $code = 'code', + string $status = 'under_verification', + int $versionNumber = 0, + string $publishedAt = 'now' + ): DraftInterface { + $productDraft = new Draft(); + $productDraft->setCode($code); + $productDraft->setStatus($status); + $productDraft->setPublishedAt(new \DateTime($publishedAt)); + $productDraft->setVersionNumber($versionNumber); + $productDraft->setProductListing($productListing); + $channel = $this->getChannel(); + $productDraft->setChannels(new ArrayCollection([$channel])); + + return $productDraft; + } + + private function createProductListingTranslation( + DraftInterface $productDraft, + string $name = 'product-listing-name', + string $description = 'product-listing-description', + string $slug = 'product-listing-slug', + string $locale = 'en_US' + ): DraftTranslationInterface { + $productTranslation = new DraftTranslation(); + $productTranslation->setLocale($locale); + $productTranslation->setSlug($slug); + $productTranslation->setName($name); + $productTranslation->setDescription($description); + $productTranslation->setProductDraft($productDraft); + + return $productTranslation; + } + + private function createProductListingPricing( + DraftInterface $productDraft, + int $price = 1000, + int $originalPrice = 1000, + int $minimumPrice = 1000, + string $channelCode = 'web_us' + ): ListingPriceInterface { + $productPricing = new ListingPrice(); + $productPricing->setProductDraft($productDraft); + $productPricing->setPrice($price); + $productPricing->setOriginalPrice($originalPrice); + $productPricing->setMinimumPrice($minimumPrice); + $productPricing->setChannelCode($channelCode); + + return $productPricing; + } + + private function getChannel(): ChannelInterface + { + return $this->entityManager->getRepository(ChannelInterface::class) + ->findAll()[0]; + } + + /** + * @Given there is conversation category :categoryName + */ + public function thereIsConversationCategory($categoryName) + { + $category = new Category(); + $category->setName($categoryName); + $this->entityManager->persist($category); + $this->entityManager->flush(); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Ui/Admin/SettlementContext.php b/OpenMarketplace/tests/Behat/Context/Ui/Admin/SettlementContext.php new file mode 100644 index 0000000..2bb78a9 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Ui/Admin/SettlementContext.php @@ -0,0 +1,136 @@ +adminSettlementPage->openSettlementsIndex(); + } + + /** + * @When I should see :count settlements with status :status + * @When I should see :count settlements + */ + public function iSeeSettlementsWithStatus(string $count, string $status = null): void + { + $settlements = $this->adminSettlementPage->getSettlementsWithStatus($status); + + Assert::eq(count($settlements), $count); + } + + /** + * @When I should see :count settlement(s) for vendor :vendorName + */ + public function iSeeSettlementsForVendor(string $count, string $vendorName): void + { + $settlements = $this->adminSettlementPage->getSettlementsForVendor($vendorName); + + Assert::eq(count($settlements), $count); + } + + /** + * @When I should see settlement total with amount of :amount for :channelName channel + */ + public function iSeeSettlementForAmountForChannel(string $amount, string $channelName): void + { + $settlements = $this->adminSettlementPage->checkExistsSettlementForAmountAndChannel($amount, $channelName); + } + + /** + * @When I filter settlements by status :status + */ + public function iFilterSettlementsByStatus(string $status): void + { + $this->adminSettlementPage->filterByStatus($status); + } + + /** + * @When I filter settlements by period :period + */ + public function iFilterSettlementsByPeriod(string $period): void + { + $this->adminSettlementPage->filterByPeriod($period); + } + + /** + * @When I filter settlements by vendor :vendor + */ + public function iFilterSettlementsByVendor(string $vendor): void + { + $this->adminSettlementPage->filterByVendor($vendor); + } + + /** + * @Then I filter settlements by channel :channelName + */ + public function iFilterSettlementsByChannel(string $channelName): void + { + $this->adminSettlementPage->filterByChannel($channelName); + } + + /** + * @Then I should see settlement for channel :channelName first + */ + public function iShouldSeeSettlementForChannelFirst(string $channelName): void + { + $sorting = $this->sharedStorage->get('sorting'); + + $settlements = $this->adminSettlementPage->getSortedSettlements($sorting); + $firstSettlement = $settlements[0]; + + Assert::contains($firstSettlement->getText(), $channelName); + } + + /** + * @Then I should see :amount settlement(s) with today as end of settlement period + */ + public function iShouldSeeSettlementsEndingToday(string $amount): void + { + $settlements = $this->adminSettlementPage->getSettlementsByPeriodEndsToday(true); + Assert::count($settlements, (int) $amount); + } + + /** + * @Then I should see :amount settlement(s) with different day as end of settlement period + */ + public function iShouldSeeSettlementsEndingDifferentDay(string $amount): void + { + $settlements = $this->adminSettlementPage->getSettlementsByPeriodEndsToday(false); + Assert::count($settlements, (int) $amount); + } + + /** + * @Then I clear settlement filters + */ + public function iClearFilters(): void + { + $this->adminSettlementPage->clearFilters(); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Ui/Admin/VendorDisablingContext.php b/OpenMarketplace/tests/Behat/Context/Ui/Admin/VendorDisablingContext.php new file mode 100644 index 0000000..f17a6eb --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Ui/Admin/VendorDisablingContext.php @@ -0,0 +1,97 @@ +entityManager = $entityManager; + $this->vendorExampleFactory = $vendorExampleFactory; + } + + /** + * @Given There is a :ifEnabled vendor + */ + public function thereIsAVendor($ifEnabled) + { + $flag = 'enabled' == $ifEnabled ? true : false; + + $options = [ + 'company_name' => 'vendor', + 'phone_number' => 'vendorPhone', + 'tax_identifier' => 'vendorTax', + 'slug' => 'slug', + 'description' => 'description', + 'enabled' => $flag, + ]; + + $vendor = $this->vendorExampleFactory->create($options); + + $this->entityManager->persist($vendor); + $this->entityManager->flush(); + } + + /** + * @When I click :buttonText + */ + public function iClick($buttonText) + { + $this->getPage()->pressButton($buttonText); + } + + /** + * @When I choose :element + */ + public function iChoose($element) + { + $page = $this->getSession()->getPage(); + $findName = $page->find('css', $element); + if (!$findName) { + throw new Exception($element . ' could not be found'); + } + $findName->click(); + } + + /** + * @Then I should not see :ifEnabled button + */ + public function iShouldNotSeeButton($ifEnabled) + { + $element = '#' . strtolower($ifEnabled); + $page = $this->getSession()->getPage(); + $findName = $page->find('css', $element); + Assert::null($findName); + } + + /** + * @return DocumentElement + */ + private function getPage() + { + return $this->getSession()->getPage(); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Ui/Admin/VendorListingContext.php b/OpenMarketplace/tests/Behat/Context/Ui/Admin/VendorListingContext.php new file mode 100644 index 0000000..88782c9 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Ui/Admin/VendorListingContext.php @@ -0,0 +1,104 @@ + 'vendor ' . $i, + 'phone_number' => 'vendorPhone' . $i, + 'tax_identifier' => 'vendorTax' . $i, + 'slug' => 'vendor-' . $i, + 'description' => 'description', + ]; + + $vendor = $this->vendorExampleFactory->create($options); + + $this->entityManager->persist($vendor); + } + $this->entityManager->flush(); + } + + /** + * @Then I should see :count vendor rows + */ + public function iShouldSeeVendorRows($count): void + { + $rows = $this->getPage()->findAll('css', 'table > tbody > tr'); + Assert::notEmpty($rows, 'Could not find any rows'); + Assert::eq($count, count($rows), 'Rows numbers are not equal'); + } + + /** + * @Then page should contain valid customer :email link + */ + public function iShouldSeeValidCustomerLink(string $email): void + { + /** @var Customer $customer */ + $customer = $this->entityManager->getRepository(Customer::class)->findOneBy(['email' => $email]); + $link = sprintf('%s', $customer->getId(), $email); + Assert::contains($this->getPage()->getHtml(), $link); + } + + /** + * @Given /^I should see vendors commission data$/ + */ + public function iShouldSeeVendorsCommissionData(): void + { + $content = $this->getPage()->getText(); + Assert::contains($content, 'Commission (%)'); + Assert::contains($content, 'Commission Type'); + } + + /** + * @Given I am on admin vendor listing page + * @Given I visit admin vendor listing page + */ + public function iAmOnAdminVendorListingPage(): void + { + $this->vendorPage->open(); + } + + /** + * @When I click edit button for :vendorName + */ + public function iClickFor(string $vendorName): void + { + $this->vendorPage->clickEditButton($vendorName); + } + + private function getPage(): DocumentElement + { + return $this->getSession()->getPage(); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Ui/Admin/VendorUpdateContext.php b/OpenMarketplace/tests/Behat/Context/Ui/Admin/VendorUpdateContext.php new file mode 100644 index 0000000..202c5f0 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Ui/Admin/VendorUpdateContext.php @@ -0,0 +1,76 @@ + 'vendor', + 'phone_number' => 'vendorPhone', + 'tax_identifier' => 'vendorTax', + 'slug' => 'slug', + 'description' => 'description', + 'status' => $ifVerified, + ]; + + $vendor = $this->vendorExampleFactory->create($options); + + if ('requested' === $ifRequested) { + $vendor->setEditedAt(new DateTime()); + } + + $this->entityManager->persist($vendor); + $this->entityManager->flush(); + } + + /** + * @Given /^I should see settlement frequency "([^"]*)"$/ + */ + public function iShouldSeeSettlementFrequency(string $frequency): void + { + $this->vendorUpdatePage->checkSettlementFrequency($frequency); + } + + /** + * @When I set settlement frequency to :frequency + */ + public function iSetSettlementFrequencyTo(string $frequency): void + { + $this->vendorUpdatePage->setSettlementFrequency($frequency); + } + + /** + * @When I submit vendor update form + */ + public function iSubmitVendorUpdateForm(): void + { + $this->vendorUpdatePage->submitVendorForm(); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Ui/Admin/VendorVerificationContext.php b/OpenMarketplace/tests/Behat/Context/Ui/Admin/VendorVerificationContext.php new file mode 100644 index 0000000..333cf41 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Ui/Admin/VendorVerificationContext.php @@ -0,0 +1,75 @@ +entityManager = $entityManager; + $this->container = $container; + $this->vendorExampleFactory = $vendorExampleFactory; + } + + /** + * @Given There is an unverified Vendor + */ + public function thereIsAnUnverifiedVendor() + { + $vendorCountry = $this->container->get('sylius.factory.country')->createNew(); + $vendorCountry->setCode('US'); + $this->entityManager->persist($vendorCountry); + + $options = [ + 'company_name' => 'vendor', + 'phone_number' => 'vendorPhone', + 'tax_identifier' => 'vendorTax', + 'street' => 'vendorStreet', + 'city' => 'vendorCity', + 'postcode' => 'vendorCode', + 'slug' => 'slug', + 'description' => 'description', + 'country' => $vendorCountry, + 'status' => 'unverified', + ]; + + $vendor = $this->vendorExampleFactory->create($options); + + $this->entityManager->persist($vendorCountry); + $this->entityManager->persist($vendor); + $this->entityManager->flush(); + } + + /** + * @When I click :buttonText + */ + public function iClick($buttonText) + { + $this->getSession()->getPage()->pressButton($buttonText); + sleep(1); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Ui/Admin/ViewPaymentContext.php b/OpenMarketplace/tests/Behat/Context/Ui/Admin/ViewPaymentContext.php new file mode 100644 index 0000000..3de210e --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Ui/Admin/ViewPaymentContext.php @@ -0,0 +1,133 @@ +entityManager = $entityManager; + $this->orderExampleFactory = $orderExampleFactory; + $this->orderRepository = $orderRepository; + $this->sharedStorage = $sharedStorage; + } + + /** + * @BeforeScenario + */ + public function clearData() + { + $purger = new ORMPurger($this->entityManager); + $purger->purge(); + } + + /** + * @Given store has primary and secondary order + */ + public function storeHasPrimaryAndSecondaryOrderWithPayment() + { + $options['complete_date'] = new \DateTime(); + $orders = $this->orderExampleFactory->createArray($options); + + foreach ($orders as $order) { + $this->orderRepository->add($order); + } + } + + /** + * @Given store has primary and secondary order with payment state :paymentState + */ + public function storeHasPrimaryAndSecondaryOrderWithPaymentState(string $paymentState) + { + $options['complete_date'] = new \DateTime(); + $orders = $this->orderExampleFactory->createArray($options); + + /** @var Order $order */ + foreach ($orders as $order) { + $order->setPaymentState($paymentState); + $this->orderRepository->add($order); + } + } + + /** + * @Then I should see :count payment(s) for :mode order(s) + */ + public function iShouldSeePayments($count, $mode) + { + $page = $this->getSession()->getPage(); + $tableWrapper = $page->find('css', 'table'); + $payments = $tableWrapper->findAll('css', '.item'); + Assert::eq(count($payments), $count); + $htmlString = $page->getHtml(); + $pattern = "/\/admin\/orders\/(\d+)/"; + preg_match_all($pattern, $htmlString, $matches); + $orderRepository = $this->entityManager->getRepository(Order::class); + $orders = $orderRepository->findBy(['id' => $matches[1]]); + foreach ($orders as $order) { + Assert::eq($order->getMode(), $mode); + } + } + + /** + * @Then statistics should omit primary order + */ + public function iViewStatistics() + { + $page = $this->getSession()->getPage(); + $totalSalesStats = $this->currencyToInt($page->find('css', '#total-sales')->getText()); + $newOrdersStats = (int) $page->find('css', '#new-orders')->getText(); + $avarageOrderValueStats = $this->currencyToInt($page->find('css', '#average-order-value')->getText()); + + /** @var Order $order */ + $order = $this->orderRepository->findOneBy(['mode' => OrderInterface::SECONDARY_ORDER_MODE]); + $channel = $this->sharedStorage->get('channel'); + $year = $order->getCheckoutCompletedAt()->format('Y'); + $startDate = new \DateTime("01-01-{$year}"); + $endDate = new \DateTime("31-12-{$year}"); + + $totalSales = $this->orderRepository->getTotalPaidSalesForChannelInPeriod($channel, $startDate, $endDate); + $newOrders = $this->orderRepository->countPaidForChannelInPeriod($channel, $startDate, $endDate); + $avarageOrderValue = $totalSales / $newOrders; + + Assert::eq($totalSalesStats, $totalSales); + Assert::eq($newOrdersStats, $newOrders); + Assert::eq($avarageOrderValueStats, $avarageOrderValue); + } + + private function currencyToInt(string $value): int + { + return (int) preg_replace('/[^0-9]/', '', $value); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Ui/Admin/ViewShipmentContext.php b/OpenMarketplace/tests/Behat/Context/Ui/Admin/ViewShipmentContext.php new file mode 100644 index 0000000..bb3349c --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Ui/Admin/ViewShipmentContext.php @@ -0,0 +1,110 @@ +entityManager = $entityManager; + $this->orderExampleFactory = $orderExampleFactory; + $this->orderRepository = $orderRepository; + $this->shipmentFactory = $shipmentFactory; + $this->sharedStorage = $sharedStorage; + $this->stateMachineFactory = $stateMachineFactory; + } + + /** + * @BeforeScenario + */ + public function clearData() + { + $purger = new ORMPurger($this->entityManager); + $purger->purge(); + } + + /** + * @Given store has primary and secondary order + */ + public function storeHasPrimaryAndSecondaryOrderWithPayment() + { + /** @var Order[] $orders */ + $orders = $this->orderExampleFactory->createArray(); + $shippingMethod = $this->sharedStorage->get('shipping_method'); + + foreach ($orders as $order) { + $shipment = $this->shipmentFactory->createNewWithOrder($order); + $shipment->setMethod($shippingMethod); + $order->addShipment($shipment); + $this->applyShipmentTransitionOnOrder($order, ShipmentTransitions::TRANSITION_CREATE); + $this->orderRepository->add($order); + } + } + + /** + * @Then I should see :count shipment(s) for :mode order(s) + */ + public function iShouldSeeShipments($count, $mode) + { + $page = $this->getSession()->getPage(); + $tableWrapper = $page->find('css', 'table'); + $shipments = $tableWrapper->findAll('css', '.item'); + Assert::eq(count($shipments), $count); + $htmlString = $page->getHtml(); + $pattern = "/\/admin\/orders\/(\d+)/"; + preg_match_all($pattern, $htmlString, $matches); + $orderRepository = $this->entityManager->getRepository(Order::class); + $orders = $orderRepository->findBy(['id' => $matches[1]]); + foreach ($orders as $order) { + Assert::eq($order->getMode(), $mode); + } + } + + private function applyShipmentTransitionOnOrder(OrderInterface $order, $transition): void + { + foreach ($order->getShipments() as $shipment) { + $this->stateMachineFactory->get($shipment, ShipmentTransitions::GRAPH)->apply($transition); + } + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Ui/Admin/VirtualWalletContext.php b/OpenMarketplace/tests/Behat/Context/Ui/Admin/VirtualWalletContext.php new file mode 100644 index 0000000..c9860ea --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Ui/Admin/VirtualWalletContext.php @@ -0,0 +1,102 @@ +virtualWalletPage->open(); + } + + /** + * @When I filter virtual wallets by vendor :vendor + */ + public function iFilterVirtualWalletsByVendor(string $vendor): void + { + $this->virtualWalletPage->filterByVendor($vendor); + } + + /** + * @Then I filter virtual wallets by channel :channelName + */ + public function iFilterVirtualWalletsByChannel(string $channelName): void + { + $this->virtualWalletPage->filterByChannel($channelName); + } + + /** + * @Then I should see virtual wallet for channel :channelName first + */ + public function iShouldSeeVirtualWalletForChannelFirst(string $channelName): void + { + $sorting = $this->sharedStorage->get('sorting'); + + $sortedVirtualWallets = $this->virtualWalletPage->getSortedVirtualWallets($sorting); + $firstVirtualWallet = $sortedVirtualWallets[0]; + + Assert::contains($firstVirtualWallet->getText(), $channelName); + } + + /** + * @Then I should see virtual wallet for vendor :vendorName first + */ + public function iShouldSeeVirtualWalletForVendorFirst(string $vendorName): void + { + $sorting = $this->sharedStorage->get('sorting'); + + $virtualWallets = $this->virtualWalletPage->getSortedVirtualWallets($sorting); + $firstVirtualWallet = $virtualWallets[0]; + + Assert::contains($firstVirtualWallet->getText(), $vendorName); + } + + /** + * @When I should see :count virtual wallets + */ + public function iSeeVirtualWallets(string $count): void + { + $settlements = $this->virtualWalletPage->getVirtualWallets(); + + Assert::eq(count($settlements), $count); + } + + /** + * @Then I should see :amount as balance for :channelName channel + */ + public function iShouldSeeAsBalanceForChannel(string $amount, string $channelName): void + { + $this->virtualWalletPage->checkExistsVirtualWalletForAmountAndChannel($amount, $channelName); + } + + /** + * @When I clear virtual wallets filters + */ + public function iClearVirtualWalletsFilters(): void + { + $this->virtualWalletPage->clearFilters(); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Ui/Shop/Account/OrderContext.php b/OpenMarketplace/tests/Behat/Context/Ui/Shop/Account/OrderContext.php new file mode 100644 index 0000000..79b5998 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Ui/Shop/Account/OrderContext.php @@ -0,0 +1,33 @@ +sharedStorage->get('primary_order'); + + $this->assertSession()->addressEquals(sprintf('/en_US/order/%s', $order->getTokenValue())); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Ui/Vendor/ProductListingContext.php b/OpenMarketplace/tests/Behat/Context/Ui/Vendor/ProductListingContext.php new file mode 100644 index 0000000..a03c163 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Ui/Vendor/ProductListingContext.php @@ -0,0 +1,385 @@ +entityManager); + $purger->purge(); + } + + /** + * @Given there is an :verified vendor user :username with password :password + */ + public function thereIsAnVendorUserWithPassword( + $verified, + $username, + $password + ) { + /** @var ShopUserInterface $user */ + $user = $this->shopUserExampleFactory->create(); + $user->setUsername($username); + $user->setPlainPassword($password); + $user->setEmail('vendor@email.com'); + $user->setVerifiedAt(new \DateTime()); + $user->addRole('ROLE_USER'); + $user->addRole('ROLE_VENDOR'); + $this->entityManager->persist($user); + + /** @var Vendor $vendor */ + $vendor = $this->vendorFactory->createNew(); + $vendor->setStatus($verified); + $vendor->setCompanyName('vendor'); + $vendor->setShopUser($user); + $vendor->setSlug('vendor-slug'); + $vendor->setDescription('description'); + $vendor->setPhoneNumber('987654321'); + $vendor->setTaxIdentifier('123456789'); + $vendor->setBankAccountNumber('iban'); + $this->entityManager->persist($vendor); + + $this->sharedStorage->set('vendor', $vendor); + $this->entityManager->flush(); + } + + /** + * @Given the product listing is removed + */ + public function thereProductListingIsRemoved() + { + $productListing = $this->sharedStorage->get('product_listing'); + $productListing->setRemoved(true); + $this->entityManager->persist($productListing); + $this->entityManager->flush(); + } + + /** + * @When I am on edit page product listing :url + */ + public function iAmOnProductListingPageWithIUrl($url) + { + $productListing = $this->sharedStorage->get('product_listing'); + $this->productListingEditVendorPage->tryToOpen(['id' => $productListing->getId()]); + } + + /** + * @Given I should see product's listing status :status + */ + public function iShouldSeeProductsListingStatus($status) + { + $productListingStatus = $this->productListingShowVendorPage->findStatus($status); + Assert::notNull($productListingStatus); + } + + /** + * @Then I should see :count product listing(s) + */ + public function iShouldSeeProductListings($count) + { + $rows = $this->productListingShowVendorPage->getTableRows(); + Assert::notEmpty($rows, 'Could not find any rows'); + Assert::eq($count, count($rows), 'Rows numbers are not equal'); + } + + /** + * @Given I click :button button + */ + public function iClickButton($button) + { + $this->getPage()->pressButton($button); + } + + /** + * @return DocumentElement + */ + private function getPage() + { + return $this->getSession()->getPage(); + } + + /** + * @Given there is :arg2 product listing created by vendor + */ + public function thereIsProductListingCreatedByVendor(int $count): void + { + $vendor = $this->sharedStorage->get('vendor'); + + for ($i = 0; $i < $count; ++$i) { + $productListing = new Listing(); + $productListing->setCode('code' . $i); + $productListing->setVendor($vendor); + + $productDraft = new Draft(); + $productDraft->setCode('code' . $i); + $productDraft->setStatus(DraftInterface::STATUS_UNDER_VERIFICATION); + $productDraft->setPublishedAt(new \DateTime()); + $productDraft->setVersionNumber(0); + $productDraft->setProductListing($productListing); + + $productTranslation = new DraftTranslation(); + $productTranslation->setLocale('en_US'); + $productTranslation->setSlug('product-listing-' . $i); + $productTranslation->setName('product-listing-' . $i); + $productTranslation->setDescription('product-listing-' . $i); + $productTranslation->setProductDraft($productDraft); + + $productPricing = new ListingPrice(); + $productPricing->setProductDraft($productDraft); + $productPricing->setPrice(1000); + $productPricing->setOriginalPrice(1000); + $productPricing->setMinimumPrice(1000); + $productPricing->setChannelCode('en_US'); + + $this->entityManager->persist($productListing); + $this->entityManager->persist($productDraft); + $this->entityManager->persist($productTranslation); + $this->entityManager->persist($productPricing); + + $this->sharedStorage->set('product_listing', $productListing); + } + + $this->entityManager->flush(); + } + + /** + * @Given there is :count product listing created by vendor with status :status + */ + public function thereIsProductListingCreatedByVendorWithStatus2( + int $count, + string $status, + ): void { + $vendor = $this->sharedStorage->get('vendor'); + + for ($i = 0; $i < $count; ++$i) { + $productListing = new Listing(); + $productListing->setCode('code' . $i); + $productListing->setVendor($vendor); + $productListing->setVerificationStatus($status); + + $productDraft = new Draft(); + $productDraft->setCode('code' . $i); + $productDraft->setStatus($status); + $productDraft->setPublishedAt(new \DateTime()); + $productDraft->setVersionNumber(0); + $productDraft->setProductListing($productListing); + + $productTranslation = new DraftTranslation(); + $productTranslation->setLocale('en_US'); + $productTranslation->setSlug('product-listing-' . $i); + $productTranslation->setName('product-listing-' . $i); + $productTranslation->setDescription('product-listing-' . $i); + $productTranslation->setProductDraft($productDraft); + + $productPricing = new ListingPrice(); + $productPricing->setProductDraft($productDraft); + $productPricing->setPrice(1000); + $productPricing->setOriginalPrice(1000); + $productPricing->setMinimumPrice(1000); + $productPricing->setChannelCode('en_US'); + + $this->entityManager->persist($productListing); + $this->entityManager->persist($productDraft); + $this->entityManager->persist($productTranslation); + $this->entityManager->persist($productPricing); + + $this->sharedStorage->set('product_listing', $productListing); + } + + $this->entityManager->flush(); + } + + /** + * @Given Product listing status is :arg1 + */ + public function productListingStatusIs($arg1): void + { + $draft = $this->entityManager->getRepository(Draft::class)->findOneBy(['code' => 'code0']); + $draft->setStatus(DraftInterface::STATUS_CREATED); + $this->entityManager->persist($draft); + $this->entityManager->flush(); + } + + /** + * @Then I should see dropdown with hide option + */ + public function iShouldSeeDropdownWithHideOption(): void + { + $dropdown = $this->productListingShowVendorPage->findDropdownLink(); + Assert::notNull($dropdown); + } + + /** + * @Then I should see url :url + */ + public function iShouldSeeUrl($url): void + { + $currentUrl = $this->getSession()->getCurrentUrl(); + $matches = preg_match($url, $currentUrl); + Assert::eq(1, $matches); + } + + /** + * @When I fill form with non unique code + */ + public function iFillFormWithNonUniqueCode(): void + { + $page = $this->getPage(); + + $page->fillField('Code', 'code0'); + $page->fillField('Price', '10'); + $page->fillField('Original price', '20'); + $page->fillField('Minimum price', '30'); + $page->fillField('Name', 'test'); + $page->fillField('Slug', 'product'); + $page->fillField('Description', 'product description'); + } + + /** + * @Then I should see non unique code error message + */ + public function iShouldSeeNonUniqueCodeMessage() + { + $text = $this->getPage()->getText(); + $isErrorMessagePresent = false !== stripos($text, 'Product Listing with given code already exists'); + Assert::true($isErrorMessagePresent); + } + + /** + * @Given I choose main taxon :taxon + */ + public function iChooseMainTaxon($taxon) + { + $page = $this->getPage(); + $page->findById('sylius_product_mainTaxon')->setValue($taxon); + } + + /** + * @Then I should get validation error + */ + public function iShouldGetValidationError() + { + $page = $this->getSession()->getPage(); + $this->getSession()->reload(); + + $label = $page->find('css', '.ui.red.label.sylius-validation-error'); + Assert::eq($label->getText(), 'You must define price for every channel.'); + } + + /** + * @Given there is an admin user :username with password :password + */ + public function thereIsAnAdminUserWithPassword($username, $password) + { + $admin = $this->adminUserExampleFactory->create(); + $admin->setUsername($username); + $admin->setPlainPassword($password); + $admin->setEmail('admin@email.com'); + $this->entityManager->persist($admin); + $this->entityManager->flush(); + + $admin->setPlainPassword($password); + $this->sharedStorage->set('admin', $admin); + } + + /** + * @Given I am logged in as an admin + */ + public function iAmLoggedInAsAnAdmin() + { + $admin = $this->sharedStorage->get('admin'); + + $this->visitPath('/admin/login'); + $this->getPage()->fillField('Username', $admin->getUsername()); + $this->getPage()->fillField('Password', $admin->getPlainPassword()); + $this->getPage()->pressButton('Login'); + ($this->getPage()->findLink('Logout')); + } + + /** + * @When I click :label on confirmation modal + */ + public function iClickOnConfirmationModal(string $label): void + { + $confirmationModal = $this->getPage()->findById($label); + $confirmationModal->click(); + } + + /** + * @Given the channel uses another locale :locales + */ + public function theChannelUsesAnotherLocale(string $locales): void + { + /** @var Channel $channel */ + $channel = $this->sharedStorage->get('channel'); + + $locale = $this->localeFactory->createNew(); + $locale->setCode($locales); + $channel->addLocale($locale); + + $this->entityManager->persist($locale); + $this->entityManager->persist($channel); + $this->entityManager->flush(); + } + + /** + * @When I fill form with default data + */ + public function iFillFormWithDefaultData(): void + { + $page = $this->getPage(); + + $page->fillField('Code', 'code'); + $page->fillField('Price', '10'); + $page->fillField('Original price', '20'); + $page->fillField('Minimum price', '30'); + $page->fillField('Name', 'test'); + $page->fillField('Slug', 'product'); + $page->fillField('Description', 'product description'); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Vendor/CustomerDashboardContext.php b/OpenMarketplace/tests/Behat/Context/Vendor/CustomerDashboardContext.php new file mode 100644 index 0000000..07a320d --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Vendor/CustomerDashboardContext.php @@ -0,0 +1,106 @@ +dashboardPage = $dashboardPage; + $this->userRepository = $userRepository; + $this->userFactory = $userFactory; + $this->manager = $manager; + $this->vendorExampleFactory = $vendorExampleFactory; + } + + /** + * @Then I should see :arg1 inside sidebar + */ + public function iShouldSeeInsideSidebar($arg1): void + { + Assert::true($this->dashboardPage->itemWithValueExistsInsideSidebar($arg1), "Cannot find $arg1 inside sidebar"); + } + + /** + * @Then I should not see :arg1 inside sidebar + */ + public function iShouldNotSeeInsideSidebar($arg1): void + { + Assert::true($this->dashboardPage->itemWithValueDoesntExistsInsideSidebar($arg1), "Found $arg1 inside sidebar"); + } + + /** + * @Given there is a :status vendor user :vendor_user_email registered in country :country_code + */ + public function thereIsAVendorUserRegisteredInCountry( + $status, + $vendor_user_email, + $country_code + ): void { + /** @var ShopUserInterface $user */ + $user = $this->userFactory->create(['email' => $vendor_user_email, 'password' => 'password', 'enabled' => true]); + $user->setVerifiedAt(new \DateTime()); + $user->addRole('ROLE_USER'); + $user->addRole('ROLE_VENDOR'); + + $this->userRepository->add($user); + + $country = $this->manager->getRepository(Country::class)->findOneBy(['code' => $country_code]); + + $options = [ + 'company_name' => 'Test', + 'phone_number' => '333333333', + 'tax_identifier' => '543455', + 'bank_account_number' => 'NL31INGB4405427607', + 'street' => 'Secret 13', + 'city' => 'Warsaw', + 'postcode' => '00-111', + 'slug' => 'vendor-slug', + 'description' => 'description', + 'country' => $country, + 'status' => $status, + ]; + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorExampleFactory->create($options); + $vendor->setShopUser($user); + $user->setVendor($vendor); + $this->manager->persist($vendor); + $this->manager->flush(); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Vendor/DraftAttributeContext.php b/OpenMarketplace/tests/Behat/Context/Vendor/DraftAttributeContext.php new file mode 100644 index 0000000..e673362 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Vendor/DraftAttributeContext.php @@ -0,0 +1,141 @@ +sharedStorage = $sharedStorage; + $this->attributeRepository = $attributeRepository; + } + + /** + * @When I fill form with :code and name with :name and submit + */ + public function iFillCodeWithAndNameWith($code, $name) + { + $page = $this->getSession()->getPage(); + $codeInput = $page->find('css', '#sylius_product_attribute_code'); + $codeInput->setValue($code); + + $nameInput = $page->find('css', '#sylius_product_attribute_translations_en_US_name'); + $nameInput->setValue($name); + + $submitButton = $page->find('css', '.ui.labeled.icon.primary.button'); + $submitButton->press(); + } + + /** + * @Then I should see attribute with :arg1 and :arg2 type :type + */ + public function iShouldSeeAttributeWithAnd( + $code, + $name, + $type + ) { + $page = $this->getSession()->getPage(); + $gridTable = $page->find('css', '.ui.sortable.stackable.very.basic.celled.table'); + $rows = $gridTable->findAll('css', '.item'); + foreach ($rows as $row) { + if ( + str_contains($row->getText(), $code) && + str_contains($row->getText(), $name) && + str_contains($row->getText(), $type) + ) { + $rowWithValueExist = true; + } + } + + assertTrue($rowWithValueExist); + } + + /** + * @Given I have Attribute type :type name :name code :code + */ + public function iHaveAttributeTypeNameCode( + $type, + $name, + $code + ) { + $vendor = $this->sharedStorage->get('vendor'); + $locale = $this->sharedStorage->get('locale'); + + $draftAttributeTranslation = new DraftAttributeTranslation(); + $draftAttributeTranslation->setLocale($locale->getCode()); + $draftAttributeTranslation->setName($name); + + $attribute = new DraftAttribute(); + $draftAttributeTranslation->setTranslatable($attribute); + + $attribute->setTranslatable(false); + $attribute->setCreatedAt(new \DateTime()); + $attribute->setVendor($vendor); + $attribute->setCode($code); + $attribute->setStorageType('text'); + $attribute->addTranslation($draftAttributeTranslation); + + $this->attributeRepository->add($attribute); + } + + /** + * @Given I fill product draft form + */ + public function iFillProductDraftForm() + { + $page = $this->getSession()->getPage(); + + $codeInput = $page->find('css', '#sylius_product_code'); + $codeInput->setValue('Testingcode'); + + $nameInput = $page->find('css', '#sylius_product_translations_en_US_name'); + $nameInput->setValue('TestingName'); + + $slugInput = $page->find('css', '#sylius_product_translations_en_US_slug'); + $slugInput->setValue('TestingSlug'); + + $priceInput = $page->find('css', '#sylius_product_productListingPrice_WEB-US_price'); + $priceInput->setValue(1); + + $originalPriceInput = $page->find('css', '#sylius_product_productListingPrice_WEB-US_originalPrice'); + $originalPriceInput->setValue(1); + + $priceInput = $page->find('css', '#sylius_product_productListingPrice_WEB-US_price'); + $priceInput->setValue(1); + } + + /** + * @Given I pick attribute + */ + public function iPickAttribute() + { + $page = $this->getSession()->getPage(); + + $wrapper = $page->find('css', '.ui.fluid.action.input'); + $wrapper->press(); + + $div = $page->find('css', '[data-value="name"]'); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Vendor/InventoryContext.php b/OpenMarketplace/tests/Behat/Context/Vendor/InventoryContext.php new file mode 100644 index 0000000..5553a4e --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Vendor/InventoryContext.php @@ -0,0 +1,47 @@ +getSession()->getPage(); + $element = $page->find('css', '#sylius_save_changes_button'); + $element->press(); + } + + /** + * @Given I set product as tracked + */ + public function iSetTracked(): void + { + $page = $this->getSession()->getPage(); + $element = $page->find('css', '#sylius_product_variant_tracked'); + $element->setValue(true); + } + + /** + * @Given I set product as untracked + */ + public function iSetUntracked(): void + { + $page = $this->getSession()->getPage(); + $element = $page->find('css', '#sylius_product_variant_tracked'); + $element->setValue(false); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Vendor/OrderContext.php b/OpenMarketplace/tests/Behat/Context/Vendor/OrderContext.php new file mode 100644 index 0000000..16a231b --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Vendor/OrderContext.php @@ -0,0 +1,102 @@ +orderShowPage = $orderShowPage; + $this->sharedStorage = $sharedStorage; + } + + /** + * @Then I should see order with number :number + */ + public function iShouldSeeOrderWithNumber(string $number): void + { + $headerText = $this->orderShowPage->getHeaderText(); + assertStringContainsString($number, $headerText); + } + + /** + * @When I visit order details page + */ + public function iAmOnOrderDetailsPage(): void + { + $order = $this->sharedStorage->get('order'); + $this->orderShowPage->open(['id' => $order->getId()]); + } + + /** + * @When I try to open order details page + */ + public function iToTryOpenOrderDetailsPage(): void + { + $order = $this->sharedStorage->get('order'); + $this->orderShowPage->tryToOpen(['id' => $order->getId()]); + } + + /** + * @Given I resend the order confirmation email as vendor + */ + public function iResendTheOrderConfirmationEmailAsVendor() + { + $this->orderShowPage->clickResendEmail(); + } + + /** + * @Then I should see customer details with name :name + */ + public function iShouldSeeCustomerDetailsWithName(string $name): void + { + $customerText = $this->orderShowPage->getCustomerText(); + assertStringContainsString($name, $customerText); + } + + /** + * @Then I should see customer billing address :address + */ + public function iShouldSeeCustomerBillingAddress(string $address): void + { + $billingAddressText = $this->orderShowPage->getBillingAddressText(); + assertStringContainsString($address, $billingAddressText); + } + + /** + * @Then I should see customer shipping address :address + */ + public function iShouldSeeCustomerShippingAddress(string $address): void + { + $shippingAddressText = $this->orderShowPage->getShippingAddressText(); + assertStringContainsString($address, $shippingAddressText); + } + + /** + * @Then I should see shipping state :state + */ + public function iShouldSeeShippingState(string $state) + { + $shippingStateText = $this->orderShowPage->getShippingStateText(); + assertStringContainsString($state, $shippingStateText); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Vendor/ProductReviewContext.php b/OpenMarketplace/tests/Behat/Context/Vendor/ProductReviewContext.php new file mode 100644 index 0000000..fe65b2a --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Vendor/ProductReviewContext.php @@ -0,0 +1,123 @@ +productReviewPage = $productReviewPage; + $this->sharedStorage = $sharedStorage; + $this->manager = $manager; + $this->productReviewRepository = $productReviewRepository; + $this->customerRepository = $customerRepository; + } + + /** + * @Then I should see :count reviews + */ + public function iShouldSeeReviews($count): void + { + $reviews = $this->productReviewPage->getReviews(); + Assert::eq(count($reviews), $count); + } + + /** + * @Given I click :button + */ + public function iClick(string $button): void + { + $this->productReviewPage->clickButton($button); + } + + /** + * @When I click :button first review + */ + public function iClickFirstReview(string $button): void + { + $this->productReviewPage->clickButtonFirstReview($button); + } + + /** + * @When I edit first review + */ + public function iEditFirstReview(): void + { + $this->productReviewPage->clickEditFirstReview(); + } + + /** + * @Then /^(this product) has (\d+) "([^"]+)" reviews$/ + */ + public function thisProductHasReview( + ProductInterface $product, + int $count, + string $status, + ): void { + $productReviews = $this->productReviewRepository->findBy(['reviewSubject' => $product, 'status' => $status]); + Assert::count($productReviews, $count); + } + + /** + * @Given /^I am on edit page of review added by "([^"]+)" to (this product)$/ + */ + public function iAmOnEditPageOfReviewAddedByToProduct(string $customer, ProductInterface $product) + { + $customer = $this->customerRepository->findOneBy(['email' => $customer]); + $productReview = $this->productReviewRepository->findOneBy(['reviewSubject' => $product, 'author' => $customer]); + $this->sharedStorage->set('review', $productReview); + + $this->productReviewPage->open(['id' => $productReview->getId()]); + } + + /** + * @Then /^(this review) should have name "([^"]+)"$/ + */ + public function thisReviewShouldHaveName(ReviewInterface $review, string $name): void + { + $this->manager->refresh($review); + Assert::same($review->getTitle(), $name); + } + + /** + * @Then /^(this review) should have comment "([^"]+)"$/ + */ + public function thisReviewShouldHaveComment(ReviewInterface $review, string $comment): void + { + $this->manager->refresh($review); + Assert::same($review->getComment(), $comment); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Vendor/SettlementContext.php b/OpenMarketplace/tests/Behat/Context/Vendor/SettlementContext.php new file mode 100644 index 0000000..8fd3be4 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Vendor/SettlementContext.php @@ -0,0 +1,79 @@ +settlementPage->openSettlementsIndex(); + } + + /** + * @When I accept first possible settlement + */ + public function iAcceptFirstPossibleSettlement(): void + { + $button = $this->settlementPage->findFirstAcceptButton(); + Assert::notNull($button); + + $button->click(); + } + + /** + * @When I should see :count settlements with status :status + * @When I should see :count settlements + */ + public function iSeeSettlementsWithStatus(string $count, string $status = null): void + { + $settlements = $this->settlementPage->getSettlementsWithStatus($status); + + Assert::eq(count($settlements), $count); + } + + /** + * @Then I should not see any accept button + */ + public function iShouldNotSeeAnyAcceptButton(): void + { + $button = $this->settlementPage->findFirstAcceptButton(); + Assert::null($button); + } + + /** + * @When I filter settlements by status :status + */ + public function iFilterSettlementsByStatus(string $status): void + { + $this->settlementPage->filterByStatus($status); + } + + /** + * @When I filter settlements by period :period + */ + public function iFilterSettlementsByPeriod(string $period): void + { + $this->settlementPage->filterByPeriod($period); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Vendor/VendorCommissionContext.php b/OpenMarketplace/tests/Behat/Context/Vendor/VendorCommissionContext.php new file mode 100644 index 0000000..f4860ce --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Vendor/VendorCommissionContext.php @@ -0,0 +1,161 @@ +orderRepository = $orderRepository; + } + + /** + * @Then commission should be calculated for each secondary order + */ + public function commissionShouldBeCalculatedForEachSecondaryOrder(): void + { + $orders = $this->orderRepository->findBy(['mode' => OrderInterface::SECONDARY_ORDER_MODE]); + + /** @var OrderInterface $order */ + foreach ($orders as $order) { + $this->testCommission($order); + } + } + + /** + * @Then commissions should not be calculated for primary orders + */ + public function commissionShouldNotBeCalculatedForPrimaryOrders(): void + { + $orders = $this->orderRepository->findBy(['mode' => OrderInterface::PRIMARY_ORDER_MODE]); + + /** @var OrderInterface $order */ + foreach ($orders as $order) { + Assert::eq(0, $order->getCommissionTotal()); + } + } + + /** + * @Then /^I should see valid commission information's$/ + */ + public function iShouldSeeCommissionInformations(): void + { + $text = $this->getSession()->getPage()->getText(); + + Assert::true(str_contains($text, 'Commission (Included in price)')); + Assert::true(str_contains($text, 'Commission:')); + + $urlArray = explode('/', $this->getSession()->getCurrentUrl()); + $orderId = (int) end($urlArray); + /** @var OrderInterface $order */ + $order = $this->orderRepository->find($orderId); + $decimalCommission = number_format($order->getCommissionTotal() / 100, 2, '.', ','); + + $this->commissionDisplayedShouldBeEqual($decimalCommission); + } + + /** + * @Then /^I should see no commission$/ + */ + public function iShouldSeeNoCommission(): void + { + $text = $this->getSession()->getPage()->getText(); + + Assert::true(str_contains($text, 'Commission (Included in price)')); + Assert::true(str_contains($text, 'Commission:')); + $this->commissionDisplayedShouldBeEqual('0.00'); + } + + /** + * @Then I should get commission value validation error + */ + public function iShouldGetValidationError(): void + { + $page = $this->getSession()->getPage(); + $this->getSession()->reload(); + + $label = $page->find('css', '.ui.red.label.sylius-validation-error'); + Assert::eq($label->getText(), 'Commission value must be positive or zero'); + } + + /** + * @Then every secondary order should have valid commission total + */ + public function everySecondaryOrderShouldHaveValidCommission(): void + { + $orders = $this->orderRepository->findBy(['mode' => OrderInterface::SECONDARY_ORDER_MODE]); + /** @var OrderInterface $order */ + foreach ($orders as $order) { + $this->testCommission($order); + } + } + + private function commissionDisplayedShouldBeEqual(string $value): void + { + $text = $this->getSession()->getPage()->getText(); + $pattern = '/Commission: \$([\d.,]+)/'; + preg_match($pattern, $text, $matches); + Assert::eq($matches[1], $value); + } + + private function calculateNetCommission(OrderInterface $order, int $commission): int + { + $floatTotal = $order->getItemsTotal() / 100; + + $floatCommission = round(($floatTotal * ($commission / 100)), 2); + $intCommission = $floatCommission * 100; + + return (int) $intCommission; + } + + private function calculateGrossCommission(OrderInterface $order, int $commission): int + { + $floatTotal = $order->getTotal() / 100; + + $floatCommission = round(($floatTotal * ($commission / 100)), 2); + $intCommission = $floatCommission * 100; + + return (int) $intCommission; + } + + private function testCommission(OrderInterface $order): void + { + $vendor = $order->getVendor(); + + if (null === $vendor) { + Assert::eq($order->getCommissionTotal(), 0); + + return; + } + + /** @var int $vendorCommission */ + $vendorCommission = $vendor->getCommission(); + $validCommissionTotal = + match ($vendor->getCommissionType()) { + VendorInterface::NET_COMMISSION => $this->calculateNetCommission($order, $vendorCommission), + VendorInterface::GROSS_COMMISSION => $this->calculateGrossCommission($order, $vendorCommission), + default => throw new \InvalidArgumentException('Invalid Commission Type') + }; + + Assert::eq($order->getCommissionTotal(), $validCommissionTotal); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Vendor/VendorRegisterContext.php b/OpenMarketplace/tests/Behat/Context/Vendor/VendorRegisterContext.php new file mode 100644 index 0000000..9bc4f36 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Vendor/VendorRegisterContext.php @@ -0,0 +1,36 @@ +vendorRegisterPage = $vendorRegisterPage; + } + + /** + * @Then I should see :itemCLass :times times + */ + public function iShouldSeeTimes($itemCLass, $times): void + { + $validationMessageCount = $this->vendorRegisterPage->getValidationMessageCount($itemCLass); + Assert::eq($times, $validationMessageCount, "expected $times got $validationMessageCount"); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Vendor/VendorSetupContext.php b/OpenMarketplace/tests/Behat/Context/Vendor/VendorSetupContext.php new file mode 100644 index 0000000..0961e8d --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Vendor/VendorSetupContext.php @@ -0,0 +1,50 @@ +sharedStorage = $sharedStorage; + $this->userRepository = $userRepository; + $this->userFactory = $userFactory; + $this->manager = $manager; + } + + /** + * @Given vendor company name is :companyName + */ + public function vendorCompanyName($companyName): void + { + $vendor = $this->sharedStorage->get('vendor'); + $vendor->setCompanyName($companyName); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Vendor/VendorShippingMethodsContext.php b/OpenMarketplace/tests/Behat/Context/Vendor/VendorShippingMethodsContext.php new file mode 100644 index 0000000..5784a9c --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Vendor/VendorShippingMethodsContext.php @@ -0,0 +1,81 @@ +getSession()->getPage()->pressButton($button); + } + + /** + * @Then I should see :name shipping method in :channel channel + */ + public function iShouldSeeShippingMethod(string $name, ChannelInterface $channel): void + { + $page = $this->getSession()->getPage(); + $channelTag = sprintf('#vendor_shipping_methods_channels_%s', $channel->getCode()); + $channelSection = $page->find('css', $channelTag); + $input = $channelSection->find('css', sprintf('input[value=%s]', $name)); + + assertNotNull($input); + assertStringContainsString($name, $input->getAttribute('value')); + } + + /** + * @Then I enable :name shipping method in :channel channel + */ + public function iEnableShippingMethod(string $name, ChannelInterface $channel): void + { + $page = $this->getSession()->getPage(); + $channelTag = sprintf('#vendor_shipping_methods_channels_%s', $channel->getCode()); + $channelSection = $page->find('css', $channelTag); + $input = $channelSection->find('css', sprintf('input[value=%s]', $name)); + $input->check(); + } + + /** + * @Then I should see :name enabled shipping method in :channel channel + */ + public function iShouldSeeEnabledShippingMethod(string $name, ChannelInterface $channel): void + { + $page = $this->getSession()->getPage(); + $channelTag = sprintf('#vendor_shipping_methods_channels_%s', $channel->getCode()); + $channelSection = $page->find('css', $channelTag); + $input = $channelSection->find('css', sprintf('input[value=%s][checked=checked]', $name)); + + assertStringContainsString($name, $input->getAttribute('value')); + } + + /** + * @Then I should see :name disabled shipping method in :channel channel + */ + public function iShouldSeeDisabledShippingMethod(string $name, ChannelInterface $channel): void + { + $page = $this->getSession()->getPage(); + $channelTag = sprintf('#vendor_shipping_methods_channels_%s', $channel->getCode()); + $channelSection = $page->find('css', $channelTag); + $input = $channelSection->find('css', sprintf('input[value=%s]:not([checked=checked])', $name)); + + assertStringContainsString($name, $input->getAttribute('value')); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/Vendor/VendorUpdateContext.php b/OpenMarketplace/tests/Behat/Context/Vendor/VendorUpdateContext.php new file mode 100644 index 0000000..b86e209 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/Vendor/VendorUpdateContext.php @@ -0,0 +1,259 @@ +sharedStorage = $sharedStorage; + $this->userRepository = $userRepository; + $this->userFactory = $userFactory; + $this->manager = $manager; + $this->vendorImageFactory = $vendorImageFactory; + $this->taxonFactory = $taxonFactory; + $this->vendorExampleFactory = $vendorExampleFactory; + $this->countryFactory = $countryFactory; + } + + /** + * @Given there is a :status vendor user :vendor_user_email registered in country :country_code + */ + public function thereIsAVendorUserRegisteredInCountry( + $status, + $vendor_user_email, + $country_code + ): void { + /** @var ShopUserInterface $user */ + $user = $this->userFactory->create(['email' => $vendor_user_email, 'password' => 'password', 'enabled' => true]); + $user->setVerifiedAt(new \DateTime()); + $user->addRole('ROLE_USER'); + $user->addRole('ROLE_VENDOR'); + + $this->sharedStorage->set('user', $user); + + $this->userRepository->add($user); + + $country = $this->manager->getRepository(Country::class)->findOneBy(['code' => $country_code]); + if (null === $country) { + /** @var CountryInterface $country */ + $country = $this->countryFactory->createNew(); + $country->setCode($country_code); + $country->enable(); + $this->manager->persist($country); + } + + $options = [ + 'company_name' => 'Test', + 'phone_number' => '333333333', + 'tax_identifier' => '543455', + 'bank_account_number' => 'NL31INGB4405427607', + 'street' => 'Secret 13', + 'city' => 'Warsaw', + 'postcode' => '00-111', + 'slug' => 'vendor-slug', + 'description' => 'description', + 'country' => $country, + 'status' => $status, + ]; + + $vendor = $this->vendorExampleFactory->create($options); + $vendor->setShopUser($user); + $this->manager->persist($vendor); + $this->manager->flush(); + $this->sharedStorage->set('vendor', $vendor); + } + + /** + * @Then Pending update data should appear in database + */ + public function pendingUpdateDataShouldAppearInDatabase() + { + $vendor = $this->sharedStorage->get('vendor'); + $pendingData = $this->manager->getRepository(ProfileUpdate::class)->findOneBy(['vendor' => $vendor]); + + Assert::notEq(null, $pendingData); + } + + /** + * @Given There is pending update data with token value :token for logged in vendor + */ + public function thereIsPendingUpdateDataWithTokenValueForLoggedInVendor($token): void + { + $vendor = $this->sharedStorage->get('vendor'); + $country = $this->manager->getRepository(Country::class)->findOneBy(['code' => 'PL']); + $pendigUpdate = new ProfileUpdate(); + $pendigUpdate->setVendorAddress(new Address()); + $pendigUpdate->setVendor($vendor); + $pendigUpdate->setToken($token); + $pendigUpdate->setCompanyName('new Company'); + $pendigUpdate->setTaxIdentifier('new ID'); + $pendigUpdate->setBankAccountNumber('new iban'); + $pendigUpdate->setPhoneNumber('new number'); + $pendigUpdate->setDescription('new description'); + $pendigUpdate->getVendorAddress()->setStreet('new street'); + $pendigUpdate->getVendorAddress()->setCity('new city'); + $pendigUpdate->getVendorAddress()->setPostalCode('new code'); + $pendigUpdate->getVendorAddress()->setCountry($country); + + $this->manager->persist($pendigUpdate); + $this->manager->flush(); + + $this->sharedStorage->set('pendingUpdate', $pendigUpdate); + } + + /** + * @Then I should get validation error + */ + public function iShouldGetValidationError() + { + $page = $this->getSession()->getPage(); + $label = $page->find('css', '.ui.red.pointing.label.sylius-validation-error'); + } + + /** + * @Given vendor have logo attached to profile + */ + public function vendorHaveLogoAttachedToProfile() + { + /** @var VendorInterface $vendor */ + $vendor = $this->sharedStorage->get('vendor'); + $path = 'path/to/file.png'; + $image = $this->vendorImageFactory->create($path, $vendor); + $vendor->setImage($image); + $this->sharedStorage->set('path', $path); + } + + /** + * @When I visit confirmation page + */ + public function iVisitConfirmationPage() + { + $repository = $this->manager->getRepository(ProfileUpdate::class); + $updateData = $repository->findAll(); + $token = $updateData[0]->getToken(); + $session = $this->getSession(); + $session->visit('/en_US/account/vendor/profile-update/' . $token); + } + + /** + * @Then Logo should be updated + */ + public function imageShouldBeUpdated() + { + $oldImagePath = $this->sharedStorage->get('path'); + $session = $this->getSession(); + $session->visit('/en_US/vendors/vendor-slug'); + + $page = $session->getPage(); + $logo = $page->find('css', '#vendor_logo'); + $newPath = $logo->getAttribute('src'); + Assert::notEq($oldImagePath, $newPath); + } + + /** + * @Given Vendor company name is :companyName tax ID is :taxId phone number is :phoneNumber + */ + public function vendorCompanyNameIsTaxIdIsPhoneNumberIs( + $companyName, + $taxId, + $phoneNumber + ) { + /** @var VendorInterface $vendor */ + $vendor = $this->sharedStorage->get('vendor'); + $vendor->setCompanyName($companyName); + $vendor->setTaxIdentifier($taxId); + $vendor->setPhoneNumber($phoneNumber); + + $this->manager->persist($vendor); + $this->manager->flush(); + $this->sharedStorage->set('vendor', $vendor); + } + + /** + * @Then I should see form initialized with :companyName :taxId :phoneNumber + */ + public function iShouldSeeAsDefaultFormValues( + $companyName, + $taxId, + $phoneNumber + ) { + $page = $this->getSession()->getPage(); + $companyNameInput = $page->find('css', '#profile_companyName'); + $taxIdInput = $page->find('css', '#profile_taxIdentifier'); + $phoneNumberInput = $page->find('css', '#profile_phoneNumber'); + + Assert::eq($companyName, $companyNameInput->getAttribute('value')); + Assert::eq($taxId, $taxIdInput->getAttribute('value')); + Assert::eq($phoneNumber, $phoneNumberInput->getAttribute('value')); + } + + /** + * @Given the channel has a menu taxon + */ + public function theChannelHasAsAMenuTaxon() + { + /** @var ChannelInterface $channel */ + $channel = $this->sharedStorage->get('channel'); + $taxon = $this->taxonFactory->createNew(); + $taxon->setCode('menu_category'); + $taxon->setName('main'); + $taxon->setSlug('main'); + $taxon->enable(); + $channel->setMenuTaxon($taxon); + + $this->manager->persist($taxon); + $this->manager->flush(); + } +} diff --git a/OpenMarketplace/tests/Behat/Context/VendorPageContext.php b/OpenMarketplace/tests/Behat/Context/VendorPageContext.php new file mode 100644 index 0000000..71e6add --- /dev/null +++ b/OpenMarketplace/tests/Behat/Context/VendorPageContext.php @@ -0,0 +1,327 @@ +entityManager = $entityManager; + $this->countryRepository = $countryRepository; + $this->vendorRepository = $vendorRepository; + $this->productFactory = $productFactory; + $this->slugGenerator = $slugGenerator; + $this->defaultVariantResolver = $defaultVariantResolver; + $this->sharedStorage = $sharedStorage; + $this->productRepository = $productRepository; + $this->channelPricingFactory = $channelPricingFactory; + $this->vendorPagePage = $vendorPagePage; + $this->vendorExampleFactory = $vendorExampleFactory; + } + + /** + * @Given there is a :vendorStatus vendor + */ + public function thereIsAVendor(string $verifiedStatus) + { + $shopUser = $this->sharedStorage->get('user'); + + $country = $this->countryRepository->findOneBy(['code' => 'US']); + + $options = [ + 'company_name' => 'test company', + 'phone_number' => '123123123', + 'tax_identifier' => '123123123', + 'street' => 'test', + 'city' => 'test', + 'postcode' => 'test', + 'slug' => 'test-company', + 'description' => 'test-company', + 'country' => $country, + 'status' => $verifiedStatus, + ]; + + $vendor = $this->vendorExampleFactory->create($options); + + $vendor->setShopUser($shopUser); + + $this->entityManager->persist($vendor); + $this->entityManager->flush(); + } + + /** + * @Given the vendor has :number products + */ + public function theVendorHasMoreThanOnePageOfProducts(int $number) + { + $vendor = $this->vendorRepository->findOneBy(['slug' => 'test-company']); + for ($i = 1; $i <= $number; ++$i) { + $this->saveProduct($this->createProduct("product-$i", $vendor)); + } + } + + /** + * @Given the vendor has :number products with different dates and prices + */ + public function theVendorHasMoreThanOnePageOfProductsWithDifferentDatesAndPrices(int $number) + { + $vendor = $this->vendorRepository->findOneBy(['slug' => 'test-company']); + if (null === $vendor) { + $vendor = $this->vendorRepository->findOneBy(['slug' => 'vendor-slug']); + } + for ($i = 1; $i <= $number; ++$i) { + $date = strtotime("+$i day", strtotime('2007-02-28')); + $this->saveProduct($this->createProduct("product-$i", $vendor, $i * 100, date('Y-m-d', $date))); + } + } + + /** + * @Then the first product should have name :name + */ + public function theFirstProductShouldHaveName(string $name): void + { + Assert::same($this->vendorPagePage->getFirstProductNameFromList(), $name); + } + + /** + * @Then the last product should have name :name + */ + public function theLastProductShouldHaveName(string $name): void + { + Assert::same($this->vendorPagePage->getLastProductNameFromList(), $name); + } + + /** + * @Then I should see :count products in the list + */ + public function iShouldSeeProductsInTheList(int $count) + { + $this->vendorPagePage->open(['vendor_slug' => 'SLUG']); + $productsCount = $this->vendorPagePage->countProduct(); + Assert::same($productsCount, $count); + } + + /** + * @Then I should see :count products on page :pageNumber + */ + public function iShouldSeeProductsOnPage(int $count, string $pageNumber) + { + $this->vendorPagePage->open( + [ + 'vendor_slug' => 'SLUG', + 'limit' => 2, + 'page' => $pageNumber, + ] + ); + $productsCount = $this->vendorPagePage->countProduct(); + + Assert::same($count, $productsCount, ); + } + + /** + * @Given sorting is set to :sortField :value + */ + public function sortingIsSetTo($sortField, $value) + { + $sortType = [ + 'ascending' => 'asc', + 'descending' => 'desc', + ]; + + $this->sharedStorage->set( + 'sorting', + [ + 'field' => $sortField, + 'value' => $sortType[$value], + ] + ); + } + + /** + * @Then i should see products sorted by :field + */ + public function iShouldSeeProductsSorted() + { + $shopSorting = $this->sharedStorage->get('sorting'); + + $this->vendorPagePage->open( + [ + 'vendor_slug' => 'SLUG', + 'sorting' => [ + $shopSorting['field'] => $shopSorting['value'], + ], + ] + ); + + assertTrue($this->vendorPagePage->productsSorted($shopSorting)); + } + + /** + * @Then I should see :count products on :slug taxon page + */ + public function iShouldSeeProductsOnTaxonPage($count, $slug) + { + $this->visit("/en_US/vendors/SLUG/taxons/$slug"); + + $page = $this->getSession()->getPage(); + $productCards = $page->findAll('css', '.ui.fluid.card'); + + Assert::count($productCards, $count); + } + + /** + * @Then I should see :count products when search for :name + */ + public function iShouldSeeProductsWhenSearchFor($count, $name) + { + $this->vendorPagePage->open( + [ + 'vendor_slug' => 'SLUG', + 'criteria' => [ + 'search' => $name, + ], + ] + ); + + $page = $this->getSession()->getPage(); + + $productCards = $page->findAll('css', '.ui.fluid.card'); + + Assert::count($productCards, $count); + } + + private function getPage(): DocumentElement + { + return $this->getSession()->getPage(); + } + + private function createProduct( + string $productName, + VendorInterface $vendor, + int $price = 100, + string $date = 'now', + ?ChannelInterface $channel = null + ): ProductInterface { + if (null === $channel && $this->sharedStorage->has('channel')) { + $channel = $this->sharedStorage->get('channel'); + } + + $date = new \DateTime($date); + + /** @var ProductInterface $product */ + $product = $this->productFactory->createWithVariant(); + + $product->setCode(StringInflector::nameToUppercaseCode($productName)); + $product->setName($productName); + $product->setSlug($this->slugGenerator->generate($productName)); + $product->setVendor($vendor); + $product->setCreatedAt($date); + + if (null !== $channel) { + $product->addChannel($channel); + + foreach ($channel->getLocales() as $locale) { + $product->setFallbackLocale($locale->getCode()); + $product->setCurrentLocale($locale->getCode()); + + $product->setName($productName); + $product->setSlug($this->slugGenerator->generate($productName)); + } + } + + /** @var ProductVariantInterface $productVariant */ + $productVariant = $this->defaultVariantResolver->getVariant($product); + + if (null !== $channel) { + $productVariant->addChannelPricing($this->createChannelPricingForChannel($price, $channel)); + } + + $productVariant->setCode($product->getCode()); + $productVariant->setName($product->getName()); + $productVariant->setCreatedAt($date); + $productVariant->setUpdatedAt($date); + + return $product; + } + + private function saveProduct(ProductInterface $product) + { + $this->productRepository->add($product); + $this->sharedStorage->set('product', $product); + } + + private function createChannelPricingForChannel(int $price, ChannelInterface $channel = null) + { + /** @var ChannelPricingInterface $channelPricing */ + $channelPricing = $this->channelPricingFactory->createNew(); + $channelPricing->setPrice($price); + $channelPricing->setChannelCode($channel->getCode()); + + return $channelPricing; + } +} diff --git a/OpenMarketplace/tests/Behat/Page/Admin/ProductListing/ShowPage.php b/OpenMarketplace/tests/Behat/Page/Admin/ProductListing/ShowPage.php new file mode 100644 index 0000000..78bd573 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Page/Admin/ProductListing/ShowPage.php @@ -0,0 +1,30 @@ +getDocument() + ->fillField( + 'mvm_conversation[messages][__name__][content]', + $message, + ); + } +} diff --git a/OpenMarketplace/tests/Behat/Page/Admin/ProductListing/ShowPageInterface.php b/OpenMarketplace/tests/Behat/Page/Admin/ProductListing/ShowPageInterface.php new file mode 100644 index 0000000..712db71 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Page/Admin/ProductListing/ShowPageInterface.php @@ -0,0 +1,19 @@ +open($sorting); + } + + public function getSettlements(): array + { + return $this->getDocument() + ->find('css', 'table.table') + ->findAll('css', 'tr.item'); + } + + public function getSettlementsWithStatus(string $status = null): array + { + $locator = null !== $status + ? sprintf('table.table > tbody > tr.item:contains("%s")', $status) + : 'table.table > tbody > tr.item' + ; + + return $this->getDocument()->findAll('css', $locator); + } + + public function getSettlementsForVendor(string $vendorName): array + { + $locator = sprintf('table.table > tbody > tr.item:contains("%s")', $vendorName); + + return $this->getDocument()->findAll('css', $locator); + } + + public function checkExistsSettlementForAmountAndChannel(string $amount, string $channelName): void + { + $locator = sprintf('table.table > tbody > tr.item:contains("%s") > td:contains("%s")', $amount, $channelName); + + $row = $this->getDocument()->find('css', $locator); + Assert::notNull($row); + } + + public function getSettlementsByPeriodEndsToday(bool $endsToday): array + { + $endsTodayString = sprintf(' - %s', date('d/m/Y')); + + $locator = $endsToday + ? sprintf('table.table > tbody > tr.item:contains("%s")', $endsTodayString) + : sprintf('table.table > tbody > tr.item:not(:contains("%s"))', $endsTodayString) + ; + + return $this->getDocument()->findAll('css', $locator); + } + + public function getSortedSettlements(array $sorting): array + { + $this->open($sorting); + + return $this->getSettlements(); + } + + public function filterByStatus(string $status): void + { + $form = $this->getForm(); + $statusDropdown = $form->find('css', 'select[id="criteria_status_status"]'); + $statusDropdown->selectOption($status); + + $form->submit(); + } + + public function filterByPeriod(string $period): void + { + $form = $this->getForm(); + $periodDropdown = $form->find('css', 'select[id="criteria_period_period"]'); + $periodDropdown->selectOption($period); + + $form->submit(); + } + + public function filterByVendor(string $vendor): void + { + $form = $this->getForm(); + $vendorDropdown = $form->find('css', 'select[id="criteria_vendor"]'); + $vendorDropdown->selectOption($vendor); + + $form->submit(); + } + + public function filterByChannel(string $channelName): void + { + $form = $this->getForm(); + $vendorDropdown = $form->find('css', 'select[id="criteria_channel"]'); + $vendorDropdown->selectOption($channelName); + + $form->submit(); + } + + public function clearFilters(): void + { + $form = $this->getForm(); + $form->clickLink('Clear filters'); + } + + private function getPage(): DocumentElement + { + return $this->getSession()->getPage(); + } + + private function getForm(): NodeElement + { + $page = $this->getPage(); + $content = $page->find('css', 'div[class="ui styled fluid accordion"]'); + + return $content->find('css', 'form'); + } +} diff --git a/OpenMarketplace/tests/Behat/Page/Admin/SettlementPageInterface.php b/OpenMarketplace/tests/Behat/Page/Admin/SettlementPageInterface.php new file mode 100644 index 0000000..7820a78 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Page/Admin/SettlementPageInterface.php @@ -0,0 +1,39 @@ +getDocument()->findAll('css', 'table.table > tbody > tr.item:contains("' . $vendorName . '")'); + $link = $row[0]->find('css', 'a:contains("Edit")'); + $link->click(); + } +} diff --git a/OpenMarketplace/tests/Behat/Page/Admin/VendorPageInterface.php b/OpenMarketplace/tests/Behat/Page/Admin/VendorPageInterface.php new file mode 100644 index 0000000..53110d5 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Page/Admin/VendorPageInterface.php @@ -0,0 +1,17 @@ +getPage()->getText(); + Assert::contains($content, $frequency); + } + + public function setSettlementFrequency(string $frequency): void + { + $settlementFrequencyField = $this->getDocument()->find('css', 'select[name="vendor[settlementFrequency]"]'); + $settlementFrequencyField->selectOption($frequency); + } + + public function submitVendorForm(): void + { + $this->getDocument()->pressButton('Save changes'); + } + + private function getPage(): DocumentElement + { + return $this->getSession()->getPage(); + } +} diff --git a/OpenMarketplace/tests/Behat/Page/Admin/VendorUpdatePageInterface.php b/OpenMarketplace/tests/Behat/Page/Admin/VendorUpdatePageInterface.php new file mode 100644 index 0000000..20c8362 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Page/Admin/VendorUpdatePageInterface.php @@ -0,0 +1,21 @@ +getDocument() + ->find('css', 'table.table') + ->findAll('css', 'tr.item'); + } + + public function getSortedVirtualWallets(array $sorting): array + { + $this->open($sorting); + + return $this->getVirtualWallets(); + } + + public function checkExistsVirtualWalletForAmountAndChannel(string $amount, string $channelName): void + { + $locator = sprintf('table.table > tbody > tr.item:contains("%s") > td:contains("%s")', $amount, $channelName); + + $row = $this->getDocument()->find('css', $locator); + Assert::notNull($row); + } + + public function filterByVendor(string $vendor): void + { + $form = $this->getForm(); + $vendorDropdown = $form->find('css', 'select[id="criteria_vendor"]'); + $vendorDropdown->selectOption($vendor); + + $form->submit(); + } + + public function filterByChannel(string $channelName): void + { + $form = $this->getForm(); + $vendorDropdown = $form->find('css', 'select[id="criteria_channel"]'); + $vendorDropdown->selectOption($channelName); + + $form->submit(); + } + + public function clearFilters(): void + { + $form = $this->getForm(); + $form->clickLink('Clear filters'); + } + + private function getPage(): DocumentElement + { + return $this->getSession()->getPage(); + } + + private function getForm(): NodeElement + { + $page = $this->getPage(); + $content = $page->find('css', 'div[class="ui styled fluid accordion"]'); + + return $content->find('css', 'form'); + } +} diff --git a/OpenMarketplace/tests/Behat/Page/Admin/VirtualWalletPageInterface.php b/OpenMarketplace/tests/Behat/Page/Admin/VirtualWalletPageInterface.php new file mode 100644 index 0000000..0aeaa65 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Page/Admin/VirtualWalletPageInterface.php @@ -0,0 +1,32 @@ +getElement('confirmation_button')->click(); + } + + public function openActionDropdown(): void + { + $this->getElement('action_dropdown')->click(); + } + + protected function getDefinedElements(): array + { + return array_merge(parent::getDefinedElements(), [ + 'action_dropdown' => '.ui.labeled.icon.floating.dropdown.link.button', + ]); + } +} diff --git a/OpenMarketplace/tests/Behat/Page/Shop/Vendor/ProductListingIndexPageInterface.php b/OpenMarketplace/tests/Behat/Page/Shop/Vendor/ProductListingIndexPageInterface.php new file mode 100644 index 0000000..9d421c1 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Page/Shop/Vendor/ProductListingIndexPageInterface.php @@ -0,0 +1,21 @@ +getDocument()->find('css', 'button'); + $addToCart->click(); + } + + private function waitForCartSummary(): void + { + if ($this->getDriver() instanceof Selenium2Driver || $this->getDriver() instanceof ChromeDriver) { + JQueryHelper::waitForAsynchronousActionsToFinish($this->getSession()); + $this->getDocument()->waitFor(3, function (): bool { + return $this->summaryPage->isOpen(); + }); + } + } +} diff --git a/OpenMarketplace/tests/Behat/Page/Vendor/Conversation/IndexPage.php b/OpenMarketplace/tests/Behat/Page/Vendor/Conversation/IndexPage.php new file mode 100644 index 0000000..0c3a2dd --- /dev/null +++ b/OpenMarketplace/tests/Behat/Page/Vendor/Conversation/IndexPage.php @@ -0,0 +1,21 @@ +getDocument()->findAll('css', '.grid .four .menu'); + foreach ($sidebars as $sidebar) { + $links = $sidebar->findAll('css', '.item'); + foreach ($links as $link) { + if ($value === $link->getText()) { + return true; + } + } + } + + return false; + } + + public function itemWithValueDoesntExistsInsideSidebar($value): bool + { + $sidebars = $this->getDocument()->findAll('css', '.grid .four .menu'); + foreach ($sidebars as $sidebar) { + $links = $sidebar->findAll('css', '.item'); + foreach ($links as $link) { + if ($value === $link->getText()) { + return false; + } + } + } + + return true; + } +} diff --git a/OpenMarketplace/tests/Behat/Page/Vendor/OrderShowPage.php b/OpenMarketplace/tests/Behat/Page/Vendor/OrderShowPage.php new file mode 100644 index 0000000..0e6efc5 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Page/Vendor/OrderShowPage.php @@ -0,0 +1,61 @@ +getDocument()->clickLink('Resend the order confirmation email'); + } + + public function getHeaderText(): string + { + $page = $this->getDocument(); + + return $page->find('css', '.ui.header')->getText(); + } + + public function getCustomerText(): string + { + $page = $this->getDocument(); + + return $page->find('css', '#customer')->getText(); + } + + public function getBillingAddressText(): string + { + $page = $this->getDocument(); + + return $page->find('css', '#billing-address')->getText(); + } + + public function getShippingAddressText(): string + { + $page = $this->getDocument(); + + return $page->find('css', '#shipping-address')->getText(); + } + + public function getShippingStateText(): string + { + $page = $this->getDocument(); + + return $page->find('css', '#shipping-state')->getText(); + } +} diff --git a/OpenMarketplace/tests/Behat/Page/Vendor/OrderShowPageInterface.php b/OpenMarketplace/tests/Behat/Page/Vendor/OrderShowPageInterface.php new file mode 100644 index 0000000..9811b75 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Page/Vendor/OrderShowPageInterface.php @@ -0,0 +1,29 @@ +getDocument() + ->fillField( + 'sylius_product[taxCategory]', + $taxCategoryName, + ); + } +} diff --git a/OpenMarketplace/tests/Behat/Page/Vendor/ProductListing/CreatePageInterface.php b/OpenMarketplace/tests/Behat/Page/Vendor/ProductListing/CreatePageInterface.php new file mode 100644 index 0000000..a74af3f --- /dev/null +++ b/OpenMarketplace/tests/Behat/Page/Vendor/ProductListing/CreatePageInterface.php @@ -0,0 +1,18 @@ +getDocument() + ->fillField( + 'sylius_product[taxCategory]', + $taxCategoryName, + ); + } +} diff --git a/OpenMarketplace/tests/Behat/Page/Vendor/ProductListing/EditPageInterface.php b/OpenMarketplace/tests/Behat/Page/Vendor/ProductListing/EditPageInterface.php new file mode 100644 index 0000000..dc2ca83 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Page/Vendor/ProductListing/EditPageInterface.php @@ -0,0 +1,18 @@ +getDocument() + ->findAll( + 'css', + 'table > tbody > tr', + ); + } + + public function findStatus(string $status): ?NodeElement + { + return $this->getDocument() + ->find( + 'css', + sprintf('table > tbody > tr > td:contains("%s")', $status), + ); + } + + public function findDropdownLink(): ?NodeElement + { + return $this->getDocument() + ->find( + 'css', + '.ui.labeled.icon.floating.dropdown.link.button', + ); + } +} diff --git a/OpenMarketplace/tests/Behat/Page/Vendor/ProductListing/IndexPageInterface.php b/OpenMarketplace/tests/Behat/Page/Vendor/ProductListing/IndexPageInterface.php new file mode 100644 index 0000000..7770501 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Page/Vendor/ProductListing/IndexPageInterface.php @@ -0,0 +1,24 @@ +getDocument(); + $tableWrapper = $page->find('css', 'table.table'); + + return $tableWrapper->findAll('css', 'tr.item'); + } + + public function clickButton(string $button): void + { + $this->getDocument()->pressButton($button); + } + + public function clickButtonFirstReview(string $button): void + { + $page = $this->getDocument(); + $firstReview = $page->find('css', 'table.table tr.item:first-child'); + $firstReview->pressButton($button); + } + + public function clickEditFirstReview(): void + { + $page = $this->getDocument(); + $editLint = $page->find('css', 'table.table tr.item:first-child a'); + $editLint->press(); + } +} diff --git a/OpenMarketplace/tests/Behat/Page/Vendor/ProductReviewPageInterface.php b/OpenMarketplace/tests/Behat/Page/Vendor/ProductReviewPageInterface.php new file mode 100644 index 0000000..06aa631 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Page/Vendor/ProductReviewPageInterface.php @@ -0,0 +1,26 @@ +open(); + } + + public function getSettlements(): array + { + return $this->getDocument() + ->find('css', 'table.table') + ->findAll('css', 'tr.item') + ; + } + + public function findFirstAcceptButton(): ?NodeElement + { + return $this->getDocument()->findButton('Accept'); + } + + public function getSettlementsWithStatus(string $status = null): array + { + $locator = null !== $status + ? sprintf('table.table > tbody > tr.item:contains("%s")', $status) + : 'table.table > tbody > tr.item' + ; + + return $this->getDocument()->findAll('css', $locator); + } + + public function filterByStatus(string $status): void + { + $form = $this->getForm(); + $statusDropdown = $form->find('css', 'select[id="criteria_status_status"]'); + $statusDropdown->selectOption($status); + + $form->submit(); + } + + public function filterByPeriod(string $period): void + { + $form = $this->getSession()->getPage()->find('css', 'form'); + $periodDropdown = $form->find('css', 'select[id="criteria_period_period"]'); + $periodDropdown->selectOption($period); + + $form->submit(); + } + + private function getForm() + { + $session = $this->getSession(); + $page = $session->getPage(); + + return $page->find('css', 'form'); + } +} diff --git a/OpenMarketplace/tests/Behat/Page/Vendor/SettlementPageInterface.php b/OpenMarketplace/tests/Behat/Page/Vendor/SettlementPageInterface.php new file mode 100644 index 0000000..1fdca2c --- /dev/null +++ b/OpenMarketplace/tests/Behat/Page/Vendor/SettlementPageInterface.php @@ -0,0 +1,29 @@ +getDocument(); + $validationMessages = $page->findAll('css', ".$messageClass"); + + return count($validationMessages); + } +} diff --git a/OpenMarketplace/tests/Behat/Page/VendorPagePage.php b/OpenMarketplace/tests/Behat/Page/VendorPagePage.php new file mode 100644 index 0000000..1340a64 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Page/VendorPagePage.php @@ -0,0 +1,72 @@ +getDocument(); + $productsList = $page->findById('products'); + + return $productsList->find('css', '[data-test-product]:first-child [data-test-product-content] [data-test-product-name]')->getText(); + } + + public function getLastProductNameFromList(): string + { + $page = $this->getDocument(); + $productsList = $page->findById('products'); + + return $productsList->find('css', '[data-test-product]:last-child [data-test-product-content] [data-test-product-name]')->getText(); + } + + public function countProduct(): int + { + $page = $this->getDocument(); + $productCards = $page->findAll('css', '.ui.fluid.card'); + + return count($productCards); + } + + public function productsSorted(array $sorting): bool + { + $page = $this->getDocument(); + + $productCards = $page->findAll('css', '.ui.fluid.card'); + + foreach ($productCards as $i => $productCard) { + $productField[$i] = $productCard->find('css', '.sylius-product-' . $sorting['field'])->getText(); + + if (0 === $i) { + continue; + } + + $comparationValue = $productField[$i - 1] <= $productField[$i]; + + if ( + ('asc' === $sorting['value'] && !$comparationValue) || + ('desc' === $sorting['value'] && $comparationValue) + ) { + return false; + } + } + + return true; + } +} diff --git a/OpenMarketplace/tests/Behat/Page/VendorPagePageInterface.php b/OpenMarketplace/tests/Behat/Page/VendorPagePageInterface.php new file mode 100644 index 0000000..e406293 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Page/VendorPagePageInterface.php @@ -0,0 +1,22 @@ +alert('Executing JS') diff --git a/OpenMarketplace/tests/Behat/Resources/services.xml b/OpenMarketplace/tests/Behat/Resources/services.xml new file mode 100644 index 0000000..a5c046e --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts.xml new file mode 100644 index 0000000..bcaafc6 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/admin/settlement.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/admin/settlement.xml new file mode 100644 index 0000000..9993de7 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/admin/settlement.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/admin/ui.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/admin/ui.xml new file mode 100644 index 0000000..3e38a8f --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/admin/ui.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/admin/view_payment.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/admin/view_payment.xml new file mode 100644 index 0000000..8ad652e --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/admin/view_payment.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/admin/view_shipment.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/admin/view_shipment.xml new file mode 100644 index 0000000..1a66ef6 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/admin/view_shipment.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/admin/virtual_wallet.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/admin/virtual_wallet.xml new file mode 100644 index 0000000..2e43cb3 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/admin/virtual_wallet.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/common/conversation_context.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/common/conversation_context.xml new file mode 100644 index 0000000..d6cb1bd --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/common/conversation_context.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/common/grid_sorting.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/common/grid_sorting.xml new file mode 100644 index 0000000..85266e1 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/common/grid_sorting.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/admin_user.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/admin_user.xml new file mode 100644 index 0000000..6f441b3 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/admin_user.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/draft_attribute.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/draft_attribute.xml new file mode 100644 index 0000000..83cf9cc --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/draft_attribute.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/paymentMethod.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/paymentMethod.xml new file mode 100644 index 0000000..c8d1aa5 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/paymentMethod.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/product.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/product.xml new file mode 100644 index 0000000..25fd61e --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/product.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/product_listing.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/product_listing.xml new file mode 100644 index 0000000..ac0588c --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/product_listing.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/settlement.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/settlement.xml new file mode 100644 index 0000000..3f3b2df --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/settlement.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/vendor.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/vendor.xml new file mode 100644 index 0000000..ae70105 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/vendor.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/virtual_wallet.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/virtual_wallet.xml new file mode 100644 index 0000000..944baa7 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/setup/virtual_wallet.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/shop/order.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/shop/order.xml new file mode 100644 index 0000000..91ef7d4 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/shop/order.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/ui/shop.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/ui/shop.xml new file mode 100644 index 0000000..a7bf483 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/ui/shop.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/customer_dashboard.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/customer_dashboard.xml new file mode 100644 index 0000000..8b620d9 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/customer_dashboard.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/draft_attribute.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/draft_attribute.xml new file mode 100644 index 0000000..1647c6a --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/draft_attribute.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/factory.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/factory.xml new file mode 100644 index 0000000..4b9cba3 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/factory.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/inventory.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/inventory.xml new file mode 100644 index 0000000..5923535 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/inventory.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/order.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/order.xml new file mode 100644 index 0000000..afa4b54 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/order.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/order_setup.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/order_setup.xml new file mode 100644 index 0000000..82ad8ae --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/order_setup.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/product_review.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/product_review.xml new file mode 100644 index 0000000..24882b1 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/product_review.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/settlement.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/settlement.xml new file mode 100644 index 0000000..36fd68d --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/settlement.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/ui.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/ui.xml new file mode 100644 index 0000000..b4ec4b1 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/ui.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/vendor_commission.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/vendor_commission.xml new file mode 100644 index 0000000..31b2bfd --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/vendor_commission.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/vendor_register.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/vendor_register.xml new file mode 100644 index 0000000..ffaf7cc --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/vendor_register.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/vendor_setup.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/vendor_setup.xml new file mode 100644 index 0000000..8657818 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/vendor_setup.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/vendor_shipping_methods.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/vendor_shipping_methods.xml new file mode 100644 index 0000000..17edf08 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/vendor_shipping_methods.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/vendor_update.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/vendor_update.xml new file mode 100644 index 0000000..5d8f78d --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor/vendor_update.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor_page.xml b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor_page.xml new file mode 100644 index 0000000..54f12bc --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/contexts/vendor_page.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/pages/Admin/settlement.xml b/OpenMarketplace/tests/Behat/Resources/services/pages/Admin/settlement.xml new file mode 100644 index 0000000..e718757 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/pages/Admin/settlement.xml @@ -0,0 +1,21 @@ + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/pages/Admin/vendor.xml b/OpenMarketplace/tests/Behat/Resources/services/pages/Admin/vendor.xml new file mode 100644 index 0000000..51ebc0f --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/pages/Admin/vendor.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/pages/Admin/virtual_wallet.xml b/OpenMarketplace/tests/Behat/Resources/services/pages/Admin/virtual_wallet.xml new file mode 100644 index 0000000..4025b57 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/pages/Admin/virtual_wallet.xml @@ -0,0 +1,21 @@ + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/pages/Shop/product_show.xml b/OpenMarketplace/tests/Behat/Resources/services/pages/Shop/product_show.xml new file mode 100644 index 0000000..9d8e611 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/pages/Shop/product_show.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/customer_dashboard.xml b/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/customer_dashboard.xml new file mode 100644 index 0000000..c4ef0b1 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/customer_dashboard.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/order_show.xml b/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/order_show.xml new file mode 100644 index 0000000..26b0f87 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/order_show.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/productListingPage.xml b/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/productListingPage.xml new file mode 100644 index 0000000..2a966c9 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/productListingPage.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/product_review.xml b/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/product_review.xml new file mode 100644 index 0000000..c4a7476 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/product_review.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/settlement.xml b/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/settlement.xml new file mode 100644 index 0000000..ae03951 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/settlement.xml @@ -0,0 +1,21 @@ + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/vendor.xml b/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/vendor.xml new file mode 100644 index 0000000..f941218 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/vendor.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/vendor_register.xml b/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/vendor_register.xml new file mode 100644 index 0000000..d3dd993 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/pages/Vendor/vendor_register.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/services/services.xml b/OpenMarketplace/tests/Behat/Resources/services/services.xml new file mode 100644 index 0000000..531a5dd --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/services/services.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/OpenMarketplace/tests/Behat/Resources/suites.yml b/OpenMarketplace/tests/Behat/Resources/suites.yml new file mode 100644 index 0000000..5159bc2 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites.yml @@ -0,0 +1,38 @@ +imports: + - suites/vendor/customer_dashboard.yml + - suites/vendor/vendor_register.yml + - suites/vendor/vendor_update.yml + - suites/vendor/vendor_commission.yml + - suites/ui/vendor/product_listing.yml + - suites/ui/admin/product_listing.yml + - suites/start_conversation.yml + - suites/ui/admin/message_categories.yml + - suites/ui/admin/managing_vendors.yml + - suites/ui/admin/verifying_vendors.yml + - suites/ui/admin/order_viewing.yml + - suites/ui/admin/viewing_payments.yml + - suites/ui/admin/viewing_shipments.yml + - suites/ui/admin/disabling_vendors.yml + - suites/ui/admin/restoring_product.yml + - suites/ui/admin/editing_vendors.yml + - suites/ui/admin/product_listing.yml + - suites/ui/admin/dashboard_statistics.yml + - suites/ui/admin/customer_orders.yml + - suites/shop/order.yml + - suites/vendor/order_listing.yml + - suites/vendor/clients_listing.yml + - suites/vendor/inventory_management.yml + - suites/vendor/order_details.yml + - suites/vendor/draft_attribute.yml + - suites/vendor/customer_details.yml + - suites/vendor/customer_details.yml + - suites/vendor/shipping_methods.yml + - suites/ui/vendor/product_delete_vendor.yml + - suites/vendor/product_reviews.yml + - suites/vendor/enable_product_listing.yml + - suites/shop/vendor_page.yml + - suites/ui/admin/product_pricing.yml + - suites/vendor/settlements.yml + - suites/ui/admin/settlements.yml + - suites/ui/admin/virtual_wallets.yml + - suites/ui/admin/settlements_frequency.yml diff --git a/OpenMarketplace/tests/Behat/Resources/suites/shop/account_order.yml b/OpenMarketplace/tests/Behat/Resources/suites/shop/account_order.yml new file mode 100644 index 0000000..c1c6a27 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/shop/account_order.yml @@ -0,0 +1,21 @@ +default: + suites: + shop_account_order: + contexts: + - tests.open_marketplace.behat.context.setup.order + - tests.open_marketplace.behat.context.setup.product + - tests.open_marketplace.behat.context.ui.shop.account.order + + - sylius.behat.context.ui.shop.account + + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.customer + - sylius.behat.context.setup.payment + - sylius.behat.context.setup.shipping + - sylius.behat.context.setup.shop_security + + - sylius.behat.context.transform.order + - sylius.behat.context.hook.doctrine_orm + - Behat\MinkExtension\Context\MinkContext + filters: + tags: "@shop_account_order&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/shop/order.yml b/OpenMarketplace/tests/Behat/Resources/suites/shop/order.yml new file mode 100644 index 0000000..484901e --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/shop/order.yml @@ -0,0 +1,25 @@ +default: + suites: + shop_order: + contexts: + - tests.open_marketplace.behat.context.shop.order + - sylius.behat.context.setup.payment + - sylius.behat.context.setup.admin_security + - tests.open_marketplace.behat.context.setup.product + - sylius.behat.context.setup.shop_security + - sylius.behat.context.setup.admin_security + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.user + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.customer + - sylius.behat.context.setup.shipping_category + - sylius.behat.context.setup.product + - sylius.behat.context.transform.shipping_category + - sylius.behat.context.setup.shipping + - sylius.behat.context.transform.shipping_method + - sylius.behat.context.transform.shared_storage + - sylius.behat.context.setup.user + - Behat\MinkExtension\Context\MinkContext + - tests.open_marketplace.behat.context.setup.payment_method + filters: + tags: "@shop_order&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/shop/vendor_page.yml b/OpenMarketplace/tests/Behat/Resources/suites/shop/vendor_page.yml new file mode 100644 index 0000000..ed8956a --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/shop/vendor_page.yml @@ -0,0 +1,16 @@ +default: + suites: + vendor_page: + contexts: + - tests.open_marketplace.behat.context.shop.order + - tests.open_marketplace.behat.context.setup.product + - tests.open_marketplace.behat.context.vendor_page_context + - tests.open_marketplace.behat.context.vendor.vendor_update_context + - sylius.behat.context.setup.shop_security + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.user + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.customer + - sylius.behat.context.setup.user + filters: + tags: "@vendor_page" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/start_conversation.yml b/OpenMarketplace/tests/Behat/Resources/suites/start_conversation.yml new file mode 100644 index 0000000..143406b --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/start_conversation.yml @@ -0,0 +1,16 @@ +default: + suites: + start_conversation: + contexts: + - tests.bitbag.open_marketplace.behat.context.vendor.vendor_setup_context + - tests.open_marketplace.behat.context.conversation_context + - sylius.behat.context.setup.shop_security + - sylius.behat.context.setup.admin_security + - sylius.behat.context.setup.admin_user + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.locale + - sylius.behat.context.ui.shop.account + - sylius.behat.context.setup.geographical + - sylius.behat.context.hook.doctrine_orm + filters: + tags: '@admin_start_conversation' diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/customer_orders.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/customer_orders.yml new file mode 100644 index 0000000..04b82de --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/customer_orders.yml @@ -0,0 +1,27 @@ +default: + suites: + customer_orders: + contexts: + - tests.open_marketplace.behat.context.shop.order + - tests.open_marketplace.behat.context.admin.view_payment_context + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.setup.order + - sylius.behat.context.setup.product + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.admin_security + - sylius.behat.context.transform.lexical + - sylius.behat.context.transform.product + - sylius.behat.context.transform.channel + - sylius.behat.context.transform.zone + - sylius.behat.context.setup.shipping + - sylius.behat.context.setup.zone + - sylius.behat.context.transform.payment + - sylius.behat.context.setup.payment + - sylius.behat.context.setup.customer + - sylius.behat.context.setup.cart + - sylius.behat.context.setup.currency + - sylius.behat.context.setup.user + - sylius.behat.context.setup.geographical + - sylius.behat.context.transform.shared_storage + filters: + tags: "@hiding_primary_orders_in_customer_tab&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/dashboard_statistics.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/dashboard_statistics.yml new file mode 100644 index 0000000..aa53956 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/dashboard_statistics.yml @@ -0,0 +1,27 @@ +default: + suites: + dashboard_statistics: + contexts: + - open_marketplace.behat.context.ui.admin.dashboard_statistics + - tests.open_marketplace.behat.context.admin.view_payment_context + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.setup.order + - sylius.behat.context.setup.product + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.admin_security + - sylius.behat.context.transform.lexical + - sylius.behat.context.transform.product + - sylius.behat.context.transform.channel + - sylius.behat.context.transform.zone + - sylius.behat.context.setup.shipping + - sylius.behat.context.setup.zone + - sylius.behat.context.transform.payment + - sylius.behat.context.setup.payment + - sylius.behat.context.setup.customer + - sylius.behat.context.setup.cart + - sylius.behat.context.setup.currency + - sylius.behat.context.setup.user + - sylius.behat.context.setup.geographical + - sylius.behat.context.transform.shared_storage + filters: + tags: "@dashboard_statistics&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/disabling_vendors.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/disabling_vendors.yml new file mode 100644 index 0000000..cf884b7 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/disabling_vendors.yml @@ -0,0 +1,10 @@ +default: + suites: + ui_disabling_vendors: + contexts: + - open_marketplace.behat.context.ui.admin.vendor_disabling + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.setup.admin_security + - sylius.behat.context.hook.doctrine_orm + filters: + tags: "@disabling_vendors&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/editing_vendors.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/editing_vendors.yml new file mode 100644 index 0000000..5ca7be4 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/editing_vendors.yml @@ -0,0 +1,10 @@ +default: + suites: + ui_editing_vendors: + contexts: + - open_marketplace.behat.context.ui.admin.vendor_editing + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.setup.admin_security + - sylius.behat.context.hook.doctrine_orm + filters: + tags: "@editing_vendors&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/managing_vendors.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/managing_vendors.yml new file mode 100644 index 0000000..17f1a50 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/managing_vendors.yml @@ -0,0 +1,13 @@ +default: + suites: + ui_managing_vendors: + contexts: + - tests.open_marketplace.behat.context.setup.admin_user + - open_marketplace.behat.context.setup.vendor + - open_marketplace.behat.context.ui.admin.vendor_listing + - open_marketplace.behat.context.ui.admin.vendor_editing + - open_marketplace.behat.context.ui.admin.admin + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.hook.doctrine_orm + filters: + tags: "@managing_vendors&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/message_categories.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/message_categories.yml new file mode 100644 index 0000000..c5599e5 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/message_categories.yml @@ -0,0 +1,13 @@ +default: + suites: + ui_message_category: + contexts: + - tests.open_marketplace.behat.context.conversation_context + - sylius.behat.context.setup.shop_security + - sylius.behat.context.setup.admin_security + - sylius.behat.context.setup.admin_user + - sylius.behat.context.ui.shop.account + - sylius.behat.context.hook.doctrine_orm + filters: + tags: '@messaging' + \ No newline at end of file diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/order_viewing.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/order_viewing.yml new file mode 100644 index 0000000..a2c2939 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/order_viewing.yml @@ -0,0 +1,27 @@ +default: + suites: + order_viewing: + contexts: + - tests.open_marketplace.behat.context.shop.order + - tests.open_marketplace.behat.context.admin.view_payment_context + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.setup.order + - sylius.behat.context.setup.product + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.admin_security + - sylius.behat.context.transform.lexical + - sylius.behat.context.transform.product + - sylius.behat.context.transform.channel + - sylius.behat.context.transform.zone + - sylius.behat.context.setup.shipping + - sylius.behat.context.setup.zone + - sylius.behat.context.transform.payment + - sylius.behat.context.setup.payment + - sylius.behat.context.setup.customer + - sylius.behat.context.setup.cart + - sylius.behat.context.setup.currency + - sylius.behat.context.setup.user + - sylius.behat.context.setup.geographical + - sylius.behat.context.transform.shared_storage + filters: + tags: "@order_viewing&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/product_listing.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/product_listing.yml new file mode 100644 index 0000000..f0ddf3b --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/product_listing.yml @@ -0,0 +1,15 @@ +default: + suites: + ui_managing_product_listings: + contexts: + - open_marketplace.behat.context.ui.admin.product_listing + - open_marketplace.behat.context.setup.product_listing + - tests.open_marketplace.behat.context.setup.draft_attribute + - tests.open_marketplace.behat.context.setup.product + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.setup.shop_security + - sylius.behat.context.setup.channel + - open_marketplace.behat.context.setup.vendor + - sylius.behat.context.hook.doctrine_orm + filters: + tags: '@managing_product_listings&&@ui' diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/product_pricing.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/product_pricing.yml new file mode 100644 index 0000000..3d59c6f --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/product_pricing.yml @@ -0,0 +1,16 @@ +default: + suites: + product_pricing: + contexts: + - sylius.behat.context.hook.doctrine_orm + - open_marketplace.behat.context.ui.admin.vendor_disabling + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.domain.managing_products + - sylius.behat.context.setup.admin_security + - sylius.behat.context.setup.product + - sylius.behat.context.setup.shop_security + - sylius.behat.context.setup.channel + - sylius.behat.context.transform.product_variant + - sylius.behat.context.setup.product + filters: + tags: "@product_pricing&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/restoring_product.yaml b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/restoring_product.yaml new file mode 100644 index 0000000..380484d --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/restoring_product.yaml @@ -0,0 +1,12 @@ +default: + suites: + restoring_visibility_admin: + contexts: + - open_marketplace.behat.context.ui.admin.product_listing + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.setup.shop_security + - sylius.behat.context.setup.channel + - open_marketplace.behat.context.setup.vendor + - sylius.behat.context.hook.doctrine_orm + filters: + tags: '@product_removal_admin@javascript&&@ui' diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/restoring_product.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/restoring_product.yml new file mode 100644 index 0000000..c70ac3e --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/restoring_product.yml @@ -0,0 +1,12 @@ +default: + suites: + restoring_visibility: + contexts: + - open_marketplace.behat.context.ui.admin.product_listing + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.setup.shop_security + - sylius.behat.context.setup.channel + - open_marketplace.behat.context.setup.vendor + - sylius.behat.context.hook.doctrine_orm + filters: + tags: '@product_removal_admin&&@ui' diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/settlements.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/settlements.yml new file mode 100644 index 0000000..a2e48a5 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/settlements.yml @@ -0,0 +1,15 @@ +default: + suites: + admin_settlements: + contexts: + - tests.open_marketplace.behat.context.admin.settlement + - tests.open_marketplace.behat.context.setup.settlement + - tests.open_marketplace.behat.context.setup.admin_user + - tests.open_marketplace.behat.context.common.grid_sorting + - open_marketplace.behat.context.setup.vendor + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.admin_security + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.user + filters: + tags: "@admin_settlements&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/settlements_frequency.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/settlements_frequency.yml new file mode 100644 index 0000000..5c7070d --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/settlements_frequency.yml @@ -0,0 +1,26 @@ +default: + suites: + admin_settlements_frequency: + contexts: + - sylius.behat.context.transform.shared_storage + - sylius.behat.context.transform.channel + - tests.open_marketplace.behat.context.setup.settlement + - tests.open_marketplace.behat.context.setup.admin_user + - tests.open_marketplace.behat.context.setup.virtual_wallet + - tests.open_marketplace.behat.context.setup.order + - open_marketplace.behat.context.setup.vendor + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.user + - sylius.behat.context.setup.admin_security + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.product + - sylius.behat.context.hook.doctrine_orm + - open_marketplace.behat.context.ui.admin.vendor_editing + - open_marketplace.behat.context.ui.admin.vendor_listing + - open_marketplace.behat.context.ui.admin.admin + - tests.open_marketplace.behat.context.admin.settlement + - tests.open_marketplace.behat.context.admin.virtual_wallet + - tests.open_marketplace.behat.context.common.grid_sorting + - sylius.behat.context.transform.lexical + filters: + tags: "@admin_settlements_frequency&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/verifying_vendors.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/verifying_vendors.yml new file mode 100644 index 0000000..d957b0f --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/verifying_vendors.yml @@ -0,0 +1,10 @@ +default: + suites: + ui_verifying_vendors: + contexts: + - open_marketplace.behat.context.ui.admin.vendor_verification + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.setup.admin_security + - sylius.behat.context.hook.doctrine_orm + filters: + tags: "@verifying_vendors&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/viewing_payments.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/viewing_payments.yml new file mode 100644 index 0000000..fcd5d9e --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/viewing_payments.yml @@ -0,0 +1,22 @@ +default: + suites: + payment_viewing: + contexts: + - tests.open_marketplace.behat.context.admin.view_payment_context + - sylius.behat.context.setup.admin_security + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.customer + - sylius.behat.context.setup.cart + - sylius.behat.context.setup.currency + - sylius.behat.context.setup.product + - sylius.behat.context.setup.shipping + - sylius.behat.context.setup.user + - sylius.behat.context.setup.geographical + - sylius.behat.context.transform.channel + - sylius.behat.context.transform.lexical + - sylius.behat.context.transform.shared_storage + - sylius.behat.context.setup.zone + - sylius.behat.context.setup.payment + - Behat\MinkExtension\Context\MinkContext + filters: + tags: "@payment_viewing&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/viewing_shipments.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/viewing_shipments.yml new file mode 100644 index 0000000..5afd514 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/viewing_shipments.yml @@ -0,0 +1,22 @@ +default: + suites: + shipment_viewing: + contexts: + - tests.open_marketplace.behat.context.admin.view_shipment_context + - sylius.behat.context.setup.admin_security + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.customer + - sylius.behat.context.setup.cart + - sylius.behat.context.setup.currency + - sylius.behat.context.setup.product + - sylius.behat.context.setup.shipping + - sylius.behat.context.setup.user + - sylius.behat.context.setup.geographical + - sylius.behat.context.transform.channel + - sylius.behat.context.transform.lexical + - sylius.behat.context.transform.shared_storage + - sylius.behat.context.setup.zone + - sylius.behat.context.setup.payment + - Behat\MinkExtension\Context\MinkContext + filters: + tags: "@shipment_viewing&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/virtual_wallets.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/virtual_wallets.yml new file mode 100644 index 0000000..dfeb745 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/admin/virtual_wallets.yml @@ -0,0 +1,20 @@ +default: + suites: + admin_virtual_wallets: + contexts: + - tests.open_marketplace.behat.context.admin.virtual_wallet + - tests.open_marketplace.behat.context.setup.virtual_wallet + - tests.open_marketplace.behat.context.setup.admin_user + - tests.open_marketplace.behat.context.common.grid_sorting + - tests.open_marketplace.behat.context.setup.product + - sylius.behat.context.setup.product + - open_marketplace.behat.context.setup.vendor + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.admin_security + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.user + - sylius.behat.context.transform.channel + - sylius.behat.context.transform.lexical + - sylius.behat.context.transform.shared_storage + filters: + tags: "@admin_virtual_wallets&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/vendor/product_delete_vendor.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/vendor/product_delete_vendor.yml new file mode 100644 index 0000000..fff048c --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/vendor/product_delete_vendor.yml @@ -0,0 +1,12 @@ +default: + suites: + restoring_visibility: + contexts: + - open_marketplace.behat.context.ui.vendor.product_listing + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.setup.shop_security + - sylius.behat.context.setup.channel + - open_marketplace.behat.context.setup.vendor + - sylius.behat.context.hook.doctrine_orm + filters: + tags: '@product_removal_vendor&&@javascript&&@ui' diff --git a/OpenMarketplace/tests/Behat/Resources/suites/ui/vendor/product_listing.yml b/OpenMarketplace/tests/Behat/Resources/suites/ui/vendor/product_listing.yml new file mode 100644 index 0000000..c4bda2a --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/ui/vendor/product_listing.yml @@ -0,0 +1,14 @@ +default: + suites: + vendor_ui_managing_product_listings: + contexts: + - open_marketplace.behat.context.ui.vendor.product_listing + - open_marketplace.behat.context.setup.product_listing + - tests.open_marketplace.behat.context.setup.draft_attribute + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.setup.channel + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.shop_security + - sylius.behat.context.setup.taxonomy + filters: + tags: '@vendor_managing_product_listings&&@ui' diff --git a/OpenMarketplace/tests/Behat/Resources/suites/vendor/clients_listing.yml b/OpenMarketplace/tests/Behat/Resources/suites/vendor/clients_listing.yml new file mode 100644 index 0000000..0d5bca1 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/vendor/clients_listing.yml @@ -0,0 +1,14 @@ +default: + suites: + clients_listing: + contexts: + - tests.open_marketplace.behat.context.shop.order + - tests.open_marketplace.behat.context.setup.order + - tests.open_marketplace.behat.context.vendor.vendor_update_context + - sylius.behat.context.setup.shop_security + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.user + - sylius.behat.context.setup.geographical + filters: + tags: "@clients_listing&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/vendor/customer_dashboard.yml b/OpenMarketplace/tests/Behat/Resources/suites/vendor/customer_dashboard.yml new file mode 100644 index 0000000..cf5fe3a --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/vendor/customer_dashboard.yml @@ -0,0 +1,11 @@ +default: + suites: + customer_dashboard: + contexts: + - tests.open_marketplace.behat.context.vendor.customer_dashboard_context + - sylius.behat.context.setup.shop_security + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.geographical + filters: + tags: "@customer_dashboard" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/vendor/customer_details.yml b/OpenMarketplace/tests/Behat/Resources/suites/vendor/customer_details.yml new file mode 100644 index 0000000..0558f96 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/vendor/customer_details.yml @@ -0,0 +1,15 @@ +default: + suites: + customers_details: + contexts: + - tests.open_marketplace.behat.context.shop.order + - tests.open_marketplace.behat.context.setup.order + - tests.open_marketplace.behat.context.vendor.vendor_update_context + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.setup.shop_security + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.user + - sylius.behat.context.setup.geographical + filters: + tags: "@customers_details&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/vendor/draft_attribute.yml b/OpenMarketplace/tests/Behat/Resources/suites/vendor/draft_attribute.yml new file mode 100644 index 0000000..ac9b1e6 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/vendor/draft_attribute.yml @@ -0,0 +1,14 @@ +default: + suites: + draft_attribute: + contexts: + - tests.open_marketplace.behat.context.draft_attribute_context + - tests.open_marketplace.behat.context.vendor.vendor_update_context + - sylius.behat.context.setup.shop_security + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.locale + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.geographical + - Behat\MinkExtension\Context\MinkContext + filters: + tags: "@draft_attribute&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/vendor/enable_product_listing.yml b/OpenMarketplace/tests/Behat/Resources/suites/vendor/enable_product_listing.yml new file mode 100644 index 0000000..2a44a5d --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/vendor/enable_product_listing.yml @@ -0,0 +1,17 @@ +default: + suites: + enable_product: + contexts: + - open_marketplace.behat.context.setup.product_listing + - tests.open_marketplace.behat.context.shop.order + - tests.open_marketplace.behat.context.setup.order + - tests.open_marketplace.behat.context.vendor.vendor_update_context + - tests.open_marketplace.behat.context.setup.product + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.setup.shop_security + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.user + - sylius.behat.context.setup.geographical + filters: + tags: "@enable_product&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/vendor/inventory_management.yml b/OpenMarketplace/tests/Behat/Resources/suites/vendor/inventory_management.yml new file mode 100644 index 0000000..d4577b8 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/vendor/inventory_management.yml @@ -0,0 +1,17 @@ +default: + suites: + inventory_management: + contexts: + - tests.open_marketplace.behat.context.vendor.inventory_context + - tests.open_marketplace.behat.context.shop.order + - tests.open_marketplace.behat.context.setup.order + - tests.open_marketplace.behat.context.vendor.vendor_update_context + - tests.open_marketplace.behat.context.setup.product + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.setup.shop_security + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.user + - sylius.behat.context.setup.geographical + filters: + tags: "@inventory_management&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/vendor/order_details.yml b/OpenMarketplace/tests/Behat/Resources/suites/vendor/order_details.yml new file mode 100644 index 0000000..2c3dea0 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/vendor/order_details.yml @@ -0,0 +1,17 @@ +default: + suites: + order_details: + contexts: + - tests.open_marketplace.behat.context.vendor.order_context + - tests.open_marketplace.behat.context.setup.order + - tests.open_marketplace.behat.context.vendor.vendor_update_context + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.setup.shop_security + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.user + - sylius.behat.context.setup.shipping + - sylius.behat.context.setup.geographical + - sylius.behat.context.transform.shared_storage + filters: + tags: "@order_details&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/vendor/order_listing.yml b/OpenMarketplace/tests/Behat/Resources/suites/vendor/order_listing.yml new file mode 100644 index 0000000..affbf5a --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/vendor/order_listing.yml @@ -0,0 +1,15 @@ +default: + suites: + order_listing: + contexts: + - tests.open_marketplace.behat.context.shop.order + - tests.open_marketplace.behat.context.setup.order + - tests.open_marketplace.behat.context.vendor.vendor_update_context + - Behat\MinkExtension\Context\MinkContext + - sylius.behat.context.setup.shop_security + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.user + - sylius.behat.context.setup.geographical + filters: + tags: "@order_listing&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/vendor/product_reviews.yml b/OpenMarketplace/tests/Behat/Resources/suites/vendor/product_reviews.yml new file mode 100644 index 0000000..02538de --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/vendor/product_reviews.yml @@ -0,0 +1,20 @@ +default: + suites: + product_reviews: + contexts: + - sylius.behat.context.setup.shop_security + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.user + - sylius.behat.context.setup.geographical + - sylius.behat.context.setup.product_review + - sylius.behat.context.setup.customer + - sylius.behat.context.transform.shared_storage + - sylius.behat.context.transform.customer + - Behat\MinkExtension\Context\MinkContext + + - tests.open_marketplace.behat.context.setup.product + - tests.open_marketplace.behat.context.vendor.vendor_update_context + - tests.open_marketplace.behat.context.vendor.product_review_context + filters: + tags: "@product_reviews&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/vendor/settlements.yml b/OpenMarketplace/tests/Behat/Resources/suites/vendor/settlements.yml new file mode 100644 index 0000000..5e8b386 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/vendor/settlements.yml @@ -0,0 +1,13 @@ +default: + suites: + vendor_settlements: + contexts: + - tests.open_marketplace.behat.context.vendor.settlement_context + - tests.open_marketplace.behat.context.setup.settlement + - open_marketplace.behat.context.setup.vendor + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.shop_security + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.user + filters: + tags: "@vendor_settlements&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/vendor/shipping_methods.yml b/OpenMarketplace/tests/Behat/Resources/suites/vendor/shipping_methods.yml new file mode 100644 index 0000000..7aed742 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/vendor/shipping_methods.yml @@ -0,0 +1,21 @@ +default: + suites: + shipping_methods: + contexts: + - sylius.behat.context.hook.doctrine_orm + + - sylius.behat.context.transform.channel + - sylius.behat.context.transform.lexical + - sylius.behat.context.transform.zone + + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.shop_security + - sylius.behat.context.setup.shipping + - sylius.behat.context.setup.user + - sylius.behat.context.setup.zone + + - tests.open_marketplace.behat.context.vendor.vendor_shipping_methods_context + - tests.open_marketplace.behat.context.vendor.vendor_update_context + - Behat\MinkExtension\Context\MinkContext + filters: + tags: "@shipping_methods&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/vendor/unverified_vendor_page.yml b/OpenMarketplace/tests/Behat/Resources/suites/vendor/unverified_vendor_page.yml new file mode 100644 index 0000000..2485f8f --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/vendor/unverified_vendor_page.yml @@ -0,0 +1,14 @@ +default: + suites: + unverified_vendor_page: + contexts: + - sylius.behat.context.hook.doctrine_orm + - tests.open_marketplace.behat.context.vendor_page_context + + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.user + + - sylius.behat.context.ui.shop.product + + filters: + tags: "@unverified_vendor_page&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/vendor/vendor_commission.yml b/OpenMarketplace/tests/Behat/Resources/suites/vendor/vendor_commission.yml new file mode 100644 index 0000000..3c7af57 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/vendor/vendor_commission.yml @@ -0,0 +1,19 @@ +default: + suites: + vendor_register: + contexts: + - open_marketplace.behat.context.ui.admin.product_listing + - sylius.behat.context.setup.shop_security + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.admin_security + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.locale + - sylius.behat.context.ui.shop.account + - tests.open_marketplace.behat.context.shop.order + - tests.open_marketplace.behat.context.setup.product + - sylius.behat.context.setup.customer + - sylius.behat.context.setup.user + - tests.bitbag.open_marketplace.behat.context.vendor.vendor_commission_context + - open_marketplace.behat.context.ui.admin.vendor_listing + filters: + tags: "@vendor_commission" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/vendor/vendor_page_pagination.yml b/OpenMarketplace/tests/Behat/Resources/suites/vendor/vendor_page_pagination.yml new file mode 100644 index 0000000..8796de6 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/vendor/vendor_page_pagination.yml @@ -0,0 +1,18 @@ +default: + suites: + vendor_page_pagination: + contexts: + - sylius.behat.context.hook.doctrine_orm + - tests.open_marketplace.behat.context.vendor_page_context + + - sylius.behat.context.setup.shop_security + - sylius.behat.context.setup.admin_security + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.locale + - sylius.behat.context.setup.user + + - sylius.behat.context.ui.shop.account + - sylius.behat.context.ui.shop.product + + filters: + tags: "@vendor_page_pagination&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/vendor/vendor_page_sorting.yml b/OpenMarketplace/tests/Behat/Resources/suites/vendor/vendor_page_sorting.yml new file mode 100644 index 0000000..22980a6 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/vendor/vendor_page_sorting.yml @@ -0,0 +1,18 @@ +default: + suites: + vendor_page_sorting: + contexts: + - sylius.behat.context.hook.doctrine_orm + - tests.open_marketplace.behat.context.vendor_page_context + + - sylius.behat.context.setup.product + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.user + + - sylius.behat.context.domain.managing_products + - sylius.behat.context.domain.notification + - sylius.behat.context.domain.security + + - sylius.behat.context.ui.shop.product + filters: + tags: "@vendor_page_sorting&&@ui" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/vendor/vendor_register.yml b/OpenMarketplace/tests/Behat/Resources/suites/vendor/vendor_register.yml new file mode 100644 index 0000000..a479fa9 --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/vendor/vendor_register.yml @@ -0,0 +1,13 @@ +default: + suites: + vendor_register: + contexts: + - tests.open_marketplace.behat.context.vendor.vendor_register_context + - sylius.behat.context.setup.shop_security + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.admin_security + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.locale + - sylius.behat.context.ui.shop.account + filters: + tags: "@vendor_register" diff --git a/OpenMarketplace/tests/Behat/Resources/suites/vendor/vendor_update.yml b/OpenMarketplace/tests/Behat/Resources/suites/vendor/vendor_update.yml new file mode 100644 index 0000000..3030b7a --- /dev/null +++ b/OpenMarketplace/tests/Behat/Resources/suites/vendor/vendor_update.yml @@ -0,0 +1,13 @@ +default: + suites: + vendor_dashboard: + contexts: + - tests.open_marketplace.behat.context.vendor.vendor_update_context + - sylius.behat.context.setup.shop_security + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.user + - sylius.behat.context.setup.geographical + - Behat\MinkExtension\Context\MinkContext + filters: + tags: "@vendor_dashboard" diff --git a/OpenMarketplace/tests/End2End/Api/CheckoutProcessEnd2EndTest.php b/OpenMarketplace/tests/End2End/Api/CheckoutProcessEnd2EndTest.php new file mode 100644 index 0000000..285294f --- /dev/null +++ b/OpenMarketplace/tests/End2End/Api/CheckoutProcessEnd2EndTest.php @@ -0,0 +1,250 @@ +loadFixturesFromFile('CheckoutProcessEnd2EndTest/test_it_for_shipment_methods_for_multiple_vendors.yml'); + $token = $this->createCartAndCheckResponse(); + $this->addProductsToCartAndCheckResponse($token); + $extractedOrderResponse = $this->fillAddressInformationAndCheckResponse($token); + $this->checkAvailableShippingMethods($token, $extractedOrderResponse['shipments']); + $this->changeDefaultShippingMethodAndCheckResponse($token, (string) $extractedOrderResponse['shipments'][1]['id']); + $this->selectPaymentMethodAndCheckResponse($token, (string) $extractedOrderResponse['payments'][0]['id']); + $this->completeCheckoutAndCheckResponse($token); + } + + private function createCartAndCheckResponse(): string + { + $response = $this->executeCreateCartRequest(); + $this->assertResponse( + $response, + 'CheckoutProcessEnd2EndTest/create_order_response', + Response::HTTP_CREATED + ); + + return $this->extractTokenValue($response); + } + + private function addProductsToCartAndCheckResponse(string $token): void + { + $response = $this->executeAddCartItemRequest($token, [ + 'productVariant' => '/api/v2/shop/product-variants/olivier_1_1', + 'quantity' => 3, + ]); + $this->assertResponse( + $response, + 'CheckoutProcessEnd2EndTest/add_item_first_product_variant_response', + Response::HTTP_CREATED + ); + + $response = $this->executeAddCartItemRequest($token, [ + 'productVariant' => '/api/v2/shop/product-variants/bruce_1_1', + 'quantity' => 1, + ]); + $this->assertResponse( + $response, + 'CheckoutProcessEnd2EndTest/add_item_second_product_variant_response', + Response::HTTP_CREATED + ); + } + + private function fillAddressInformationAndCheckResponse(string $token): array + { + $response = $this->executeAddAddressInformationToOrderRequest($token); + $this->assertResponse( + $response, + 'CheckoutProcessEnd2EndTest/add_addresses_information_response', + Response::HTTP_OK + ); + + return $this->extractResponse($response); + } + + private function checkAvailableShippingMethods(string $token, array $shipments): void + { + $response = $this->executeGetShipmentMethodsRequest($token, (string) $shipments[0]['id']); + $this->assertResponse($response, 'CheckoutProcessEnd2EndTest/get_first_shipment_available_shipping_methods_response', Response::HTTP_OK); + + $response = $this->executeGetShipmentMethodsRequest($token, (string) $shipments[1]['id']); + $this->assertResponse($response, 'CheckoutProcessEnd2EndTest/get_second_shipment_available_shipping_methods_response', Response::HTTP_OK); + } + + private function changeDefaultShippingMethodAndCheckResponse(string $token, $shipmentId): void + { + $response = $this->executeChangeDefaultShippingMethodRequest($token, $shipmentId); + $this->assertResponse( + $response, + 'CheckoutProcessEnd2EndTest/change_default_shipping_method_for_second_shipment_response', + Response::HTTP_OK + ); + } + + private function selectPaymentMethodAndCheckResponse(string $token, string $paymentId): void + { + $response = $this->executeSelectPaymentMethodRequest($token, $paymentId); + $this->assertResponse( + $response, + 'CheckoutProcessEnd2EndTest/select_payment_method_response', + Response::HTTP_OK + ); + } + + private function completeCheckoutAndCheckResponse(string $token): void + { + $response = $this->executeCompleteCheckoutRequest($token); + $this->assertResponse( + $response, + 'CheckoutProcessEnd2EndTest/complete_checkout_response', + Response::HTTP_OK + ); + } + + private function executeCreateCartRequest(): Response + { + $this->client->request( + 'POST', + '/api/v2/shop/orders', + [], + [], + self::CONTENT_TYPE_HEADER, + json_encode([]) + ); + + return $this->client->getResponse(); + } + + private function extractTokenValue(Response $response): string + { + $data = json_decode($response->getContent(), true); + + return $data['tokenValue']; + } + + private function executeAddCartItemRequest(string $token, array $data): Response + { + $this->client->request( + 'POST', + '/api/v2/shop/orders/' . $token . '/items', + [], + [], + self::CONTENT_TYPE_HEADER, + json_encode($data) + ); + + return $this->client->getResponse(); + } + + private function executeAddAddressInformationToOrderRequest(string $token): Response + { + $this->client->request( + 'PUT', + '/api/v2/shop/orders/' . $token, + [], + [], + self::CONTENT_TYPE_HEADER, + json_encode([ + 'email' => 'test@bigbag.com', + 'shippingAddress' => [ + 'firstName' => 'John', + 'lastName' => 'Novak', + 'countryCode' => 'PL', + 'city' => 'Warszawa', + 'street' => 'Testowa 3', + 'postcode' => '11-123', + ], + 'billingAddress' => [ + 'firstName' => 'John', + 'lastName' => 'Novak', + 'countryCode' => 'PL', + 'city' => 'Warszawa', + 'street' => 'Testowa 3', + 'postcode' => '11-123', + ], + 'quantity' => 1, + ]) + ); + + return $this->client->getResponse(); + } + + private function extractResponse(Response $response): array + { + return json_decode($response->getContent(), true); + } + + private function executeGetShipmentMethodsRequest(string $token, string $shipmentsIds): Response + { + $this->client->request( + 'GET', + '/api/v2/shop/orders/' . $token . '/shipments/' . $shipmentsIds . '/methods', + [], + [], + self::CONTENT_TYPE_HEADER + ); + + return $this->client->getResponse(); + } + + private function executeChangeDefaultShippingMethodRequest(string $token, string $shipmentsIds): Response + { + $this->client->request( + 'PATCH', + '/api/v2/shop/orders/' . $token . '/shipments/' . $shipmentsIds, + [], + [], + ['CONTENT_TYPE' => 'application/merge-patch+json', 'HTTP_ACCEPT' => 'application/ld+json'], + json_encode([ + 'shippingMethod' => '/api/v2/shop/shipping-methods/fedex', + ]) + ); + + return $this->client->getResponse(); + } + + private function executeSelectPaymentMethodRequest(string $token, string $paymentId): Response + { + $this->client->request( + 'PATCH', + '/api/v2/shop/orders/' . $token . '/payments/' . $paymentId, + [], + [], + ['CONTENT_TYPE' => 'application/merge-patch+json', 'HTTP_ACCEPT' => 'application/ld+json'], + json_encode([ + 'paymentMethod' => '/api/v2/shop/payment-methods/CASH_ON_DELIVERY', + ]) + ); + + return $this->client->getResponse(); + } + + private function executeCompleteCheckoutRequest(string $token): Response + { + $this->client->request( + 'PATCH', + '/api/v2/shop/orders/' . $token . '/complete', + [], + [], + ['CONTENT_TYPE' => 'application/merge-patch+json', 'HTTP_ACCEPT' => 'application/ld+json'], + json_encode([ + 'notes' => 'notes', + ]) + ); + + return $this->client->getResponse(); + } +} diff --git a/OpenMarketplace/tests/End2End/DataFixtures/ORM/CheckoutProcessEnd2EndTest/test_it_for_shipment_methods_for_multiple_vendors.yml b/OpenMarketplace/tests/End2End/DataFixtures/ORM/CheckoutProcessEnd2EndTest/test_it_for_shipment_methods_for_multiple_vendors.yml new file mode 100644 index 0000000..d58eaf4 --- /dev/null +++ b/OpenMarketplace/tests/End2End/DataFixtures/ORM/CheckoutProcessEnd2EndTest/test_it_for_shipment_methods_for_multiple_vendors.yml @@ -0,0 +1,212 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Addressing\Model\Zone: + pl: + code: 'PL' + name: 'Poland' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_pl: + code: 'PL' + belongsTo: '@pl' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' + locale_2: + createdAt: '' + code: 'pl_PL' +Sylius\Component\Core\Model\Channel: + channel: + code: "CODE" + name: "name" + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: "John" + lastName: "Nowak" + email: "test@example.com" + emailCanonical: "test2@example.com" + customer_bruce: + firstName: "Bruce" + lastName: "Wayne" + email: "test2@example.com" + emailCanonical: "test@example.com" +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: "123password" + roles: ["ROLE_USER"] + enabled: "true" + customer: '@customer_oliver' + username: "oliver@queen.com" + usernameCanonical: "oliver@queen.com" + user_bruce: + plainPassword: "123password" + roles: ["ROLE_USER"] + enabled: "true" + customer: '@customer_bruce' + username: "bruce@wayne.com" + usernameCanonical: "bruce@wayne.com" +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + oliver_vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' + bruce_vendor_address: + country: '@poland' + city: 'Poznan' + postalCode: '61-512' + street: 'Umultowska 54' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL96109024023279659782853256' + phoneNumber: '333111222' + vendorAddress: '@oliver_vendor_address' + slug: 'oliver-queen-company' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL43109024021774571831923272' + phoneNumber: '333111222' + vendorAddress: '@bruce_vendor_address' + slug: 'bruce-wayne-company' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + vendor_olivier_first_product: + vendor: '@vendor_oliver' + code: "olivier_1" + enabled: true + channels: ['@channel'] + vendor_bruce_first_product: + vendor: '@vendor_bruce' + code: "bruce_1" + enabled: true + channels: ['@channel'] +Sylius\Component\Core\Model\ProductTranslation: + vendor_olivier_first_product_translation: + slug: 'olivier_first_product' + locale: 'en_US' + name: 'olivier_first_product' + description: '' + translatable: '@vendor_olivier_first_product' + vendor_bruce_first_product_translation: + slug: 'bruce_first_product' + locale: 'en_US' + name: 'bruce_first_product' + description: '' + translatable: '@vendor_bruce_first_product' +Sylius\Component\Core\Model\ProductVariant: + vendor_olivier_first_product_variant: + product: '@vendor_olivier_first_product' + code: "olivier_1_1" + enabled: true + onHand: 3 + tracked: true + vendor_bruce_first_product_variant: + product: '@vendor_bruce_first_product' + code: "bruce_1_1" + enabled: true + onHand: 3 + tracked: true +Sylius\Component\Core\Model\ChannelPricing: + vendor_olivier_first_product_variant_pricing: + price: 10 + originalPrice: 15 + minimumPrice: 0 + channelCode: 'CODE' + productVariant: '@vendor_olivier_first_product_variant' + vendor_bruce_first_product_variant_pricing: + price: 11 + originalPrice: 16 + minimumPrice: 0 + channelCode: 'CODE' + productVariant: '@vendor_bruce_first_product_variant' +Sylius\Component\Product\Model\ProductVariantTranslation: + vendor_olivier_first_product_variant_translation: + locale: 'en_US' + name: 'vendor_olivier_first_product_variant' + translatable: '@vendor_olivier_first_product_variant' + vendor_bruce_first_product_variant_translation: + locale: 'en_US' + name: 'vendor_bruce_first_product_variant' + translatable: '@vendor_bruce_first_product_variant' +Sylius\Component\Core\Model\ShippingMethod: + shipping_method_ups: + code: 'ups' + calculator: 'flat_rate' + zone: '@pl' + enabled: true + channels: ['@channel'] + configuration: + CODE: + amount: 5 + shipping_method_fedex: + code: 'fedex' + calculator: 'flat_rate' + zone: '@pl' + enabled: true + channels: ['@channel'] + configuration: + CODE: + amount: 5 +Sylius\Component\Shipping\Model\ShippingMethodTranslation: + shipping_method_ups_translation: + translatable: '@shipping_method_ups' + name: 'ups' + locale: 'en_US' + shipping_method_fedex_translation: + translatable: '@shipping_method_fedex' + name: 'fedex' + locale: 'en_US' +BitBag\OpenMarketplace\Component\Vendor\Entity\VendorShippingMethod: + vendor_olivier_shipping_method_ups: + vendor: '@vendor_oliver' + shippingMethod: '@shipping_method_ups' + channelCode: 'CODE' + vendor_bruce_shipping_method_fedex: + vendor: '@vendor_bruce' + shippingMethod: '@shipping_method_fedex' + channelCode: 'CODE' + vendor_bruce_shipping_method_ups: + vendor: '@vendor_bruce' + shippingMethod: '@shipping_method_ups' + channelCode: 'CODE' +Sylius\Component\Core\Model\PaymentMethod: + payment_method_cash_on_delivery: + code: 'CASH_ON_DELIVERY' + enabled: true + gatewayConfig: '@gateway_offline' + currentLocale: 'en_US' + translations: + - '@payment_method_cash_on_delivery_translation' + channels: ['@channel'] +Sylius\Component\Payment\Model\PaymentMethodTranslation: + payment_method_cash_on_delivery_translation: + name: 'Cash on delivery' + locale: 'en_US' + description: '' + translatable: '@payment_method_cash_on_delivery' +Sylius\Bundle\PayumBundle\Model\GatewayConfig: + gateway_offline: + gatewayName: 'Offline' + factoryName: 'offline' + config: [] diff --git a/OpenMarketplace/tests/End2End/End2EndTestCase.php b/OpenMarketplace/tests/End2End/End2EndTestCase.php new file mode 100644 index 0000000..591f195 --- /dev/null +++ b/OpenMarketplace/tests/End2End/End2EndTestCase.php @@ -0,0 +1,28 @@ +dataFixturesPath = __DIR__ . '/DataFixtures/ORM'; + $this->expectedResponsesPath = __DIR__ . '/Responses/Expected'; + } +} diff --git a/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/add_addresses_information_response.json b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/add_addresses_information_response.json new file mode 100644 index 0000000..244973b --- /dev/null +++ b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/add_addresses_information_response.json @@ -0,0 +1,99 @@ +{ + "@context": "\/api\/v2\/contexts\/Order", + "@id": "\/api\/v2\/shop\/orders\/@string@", + "@type": "Order", + "shippingAddress": { + "@id": "\/api\/v2\/shop\/addresses\/@integer@", + "@type": "Address", + "firstName": "John", + "lastName": "Novak", + "countryCode": "PL", + "street": "Testowa 3", + "city": "Warszawa", + "postcode": "11-123" + }, + "billingAddress": { + "@id": "\/api\/v2\/shop\/addresses\/@integer@", + "@type": "Address", + "firstName": "John", + "lastName": "Novak", + "countryCode": "PL", + "street": "Testowa 3", + "city": "Warszawa", + "postcode": "11-123" + }, + "payments": [ + { + "@id": "\/api\/v2\/shop\/payments\/@integer@", + "@type": "Payment", + "id": "@integer@", + "method": "\/api\/v2\/shop\/payment-methods\/CASH_ON_DELIVERY" + } + ], + "shipments": [ + { + "@id": "\/api\/v2\/shop\/shipments\/@integer@", + "@type": "Shipment", + "id": "@integer@", + "method": "\/api\/v2\/shop\/shipping-methods\/ups", + "vendor": { + "@id": "\/api\/v2\/shop\/vendors\/@string@", + "@type": "Vendor", + "uuid": "@string@", + "slug": "oliver-queen-company" + } + }, + { + "@id": "\/api\/v2\/shop\/shipments\/@integer@", + "@type": "Shipment", + "id": "@integer@", + "method": "\/api\/v2\/shop\/shipping-methods\/fedex", + "vendor": { + "@id": "\/api\/v2\/shop\/vendors\/@string@", + "@type": "Vendor", + "uuid": "@string@", + "slug": "bruce-wayne-company" + } + } + ], + "currencyCode": "USD", + "localeCode": "en_US", + "checkoutState": "addressed", + "paymentState": "cart", + "shippingState": "cart", + "tokenValue": "@string@", + "id": "@integer@", + "items": [ + { + "@id": "\/api\/v2\/shop\/order-items\/@integer@", + "@type": "OrderItem", + "variant": "\/api\/v2\/shop\/product-variants\/olivier_1_1", + "productName": "olivier_first_product", + "id": "@integer@", + "quantity": 3, + "unitPrice": 10, + "originalUnitPrice": 15, + "total": 30, + "discountedUnitPrice": 10, + "subtotal": 30 + }, + { + "@id": "\/api\/v2\/shop\/order-items\/@integer@", + "@type": "OrderItem", + "variant": "\/api\/v2\/shop\/product-variants\/bruce_1_1", + "productName": "bruce_first_product", + "id": "@integer@", + "quantity": 1, + "unitPrice": 11, + "originalUnitPrice": 16, + "total": 11, + "discountedUnitPrice": 11, + "subtotal": 11 + } + ], + "itemsTotal": 41, + "total": 51, + "taxTotal": 0, + "shippingTotal": 10, + "orderPromotionTotal": 0 +} diff --git a/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/add_item_first_product_variant_response.json b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/add_item_first_product_variant_response.json new file mode 100644 index 0000000..af87b47 --- /dev/null +++ b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/add_item_first_product_variant_response.json @@ -0,0 +1,54 @@ +{ + "@context": "\/api\/v2\/contexts\/Order", + "@id": "\/api\/v2\/shop\/orders\/@string@", + "@type": "Order", + "payments": [ + { + "@id": "\/api\/v2\/shop\/payments\/@integer@", + "@type": "Payment", + "id": "@integer@", + "method": "\/api\/v2\/shop\/payment-methods\/CASH_ON_DELIVERY" + } + ], + "shipments": { + "0": { + "@id": "\/api\/v2\/shop\/shipments\/@integer@", + "@type": "Shipment", + "id": "@integer@", + "method": "\/api\/v2\/shop\/shipping-methods\/ups", + "vendor": { + "@id": "\/api\/v2\/shop\/vendors\/@string@", + "@type": "Vendor", + "uuid": "@string@", + "slug": "oliver-queen-company" + } + } + }, + "currencyCode": "USD", + "localeCode": "en_US", + "checkoutState": "cart", + "paymentState": "cart", + "shippingState": "cart", + "tokenValue": "@string@", + "id": "@integer@", + "items": [ + { + "@id": "\/api\/v2\/shop\/order-items\/@integer@", + "@type": "OrderItem", + "variant": "\/api\/v2\/shop\/product-variants\/olivier_1_1", + "productName": "olivier_first_product", + "id": "@integer@", + "quantity": 3, + "unitPrice": 10, + "originalUnitPrice": 15, + "total": 30, + "discountedUnitPrice": 10, + "subtotal": 30 + } + ], + "itemsTotal": 30, + "total": 35, + "taxTotal": 0, + "shippingTotal": 5, + "orderPromotionTotal": 0 +} diff --git a/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/add_item_second_product_variant_response.json b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/add_item_second_product_variant_response.json new file mode 100644 index 0000000..28630ea --- /dev/null +++ b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/add_item_second_product_variant_response.json @@ -0,0 +1,79 @@ +{ + "@context": "\/api\/v2\/contexts\/Order", + "@id": "\/api\/v2\/shop\/orders\/@string@", + "@type": "Order", + "payments": [ + { + "@id": "\/api\/v2\/shop\/payments\/@integer@", + "@type": "Payment", + "id": "@integer@", + "method": "\/api\/v2\/shop\/payment-methods\/CASH_ON_DELIVERY" + } + ], + "shipments": { + "0": { + "@id": "\/api\/v2\/shop\/shipments\/@integer@", + "@type": "Shipment", + "id": "@integer@", + "method": "\/api\/v2\/shop\/shipping-methods\/ups", + "vendor": { + "@id": "\/api\/v2\/shop\/vendors\/@string@", + "@type": "Vendor", + "uuid": "@string@", + "slug": "oliver-queen-company" + } + }, + "1": { + "@id": "\/api\/v2\/shop\/shipments\/@integer@", + "@type": "Shipment", + "id": "@integer@", + "method": "\/api\/v2\/shop\/shipping-methods\/fedex", + "vendor": { + "@id": "\/api\/v2\/shop\/vendors\/@string@", + "@type": "Vendor", + "uuid": "@string@", + "slug": "bruce-wayne-company" + } + } + }, + "currencyCode": "USD", + "localeCode": "en_US", + "checkoutState": "cart", + "paymentState": "cart", + "shippingState": "cart", + "tokenValue": "@string@", + "id": "@integer@", + "items": [ + { + "@id": "\/api\/v2\/shop\/order-items\/@integer@", + "@type": "OrderItem", + "variant": "\/api\/v2\/shop\/product-variants\/olivier_1_1", + "productName": "olivier_first_product", + "id": "@integer@", + "quantity": 3, + "unitPrice": 10, + "originalUnitPrice": 15, + "total": 30, + "discountedUnitPrice": 10, + "subtotal": 30 + }, + { + "@id": "\/api\/v2\/shop\/order-items\/@integer@", + "@type": "OrderItem", + "variant": "\/api\/v2\/shop\/product-variants\/bruce_1_1", + "productName": "bruce_first_product", + "id": "@integer@", + "quantity": 1, + "unitPrice": 11, + "originalUnitPrice": 16, + "total": 11, + "discountedUnitPrice": 11, + "subtotal": 11 + } + ], + "itemsTotal": 41, + "total": 51, + "taxTotal": 0, + "shippingTotal": 10, + "orderPromotionTotal": 0 +} diff --git a/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/change_default_shipping_method_for_second_shipment_response.json b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/change_default_shipping_method_for_second_shipment_response.json new file mode 100644 index 0000000..5988585 --- /dev/null +++ b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/change_default_shipping_method_for_second_shipment_response.json @@ -0,0 +1,99 @@ +{ + "@context": "\/api\/v2\/contexts\/Order", + "@id": "\/api\/v2\/shop\/orders\/@string@", + "@type": "Order", + "shippingAddress": { + "@id": "\/api\/v2\/shop\/addresses\/@integer@", + "@type": "Address", + "firstName": "John", + "lastName": "Novak", + "countryCode": "PL", + "street": "Testowa 3", + "city": "Warszawa", + "postcode": "11-123" + }, + "billingAddress": { + "@id": "\/api\/v2\/shop\/addresses\/@integer@", + "@type": "Address", + "firstName": "John", + "lastName": "Novak", + "countryCode": "PL", + "street": "Testowa 3", + "city": "Warszawa", + "postcode": "11-123" + }, + "payments": [ + { + "@id": "\/api\/v2\/shop\/payments\/@integer@", + "@type": "Payment", + "id": "@integer@", + "method": "\/api\/v2\/shop\/payment-methods\/CASH_ON_DELIVERY" + } + ], + "shipments": [ + { + "@id": "\/api\/v2\/shop\/shipments\/@integer@", + "@type": "Shipment", + "id": "@integer@", + "method": "\/api\/v2\/shop\/shipping-methods\/ups", + "vendor": { + "@id": "\/api\/v2\/shop\/vendors\/@string@", + "@type": "Vendor", + "uuid": "@string@", + "slug": "oliver-queen-company" + } + }, + { + "@id": "\/api\/v2\/shop\/shipments\/@integer@", + "@type": "Shipment", + "id": "@integer@", + "method": "\/api\/v2\/shop\/shipping-methods\/fedex", + "vendor": { + "@id": "\/api\/v2\/shop\/vendors\/@string@", + "@type": "Vendor", + "uuid": "@string@", + "slug": "bruce-wayne-company" + } + } + ], + "currencyCode": "USD", + "localeCode": "en_US", + "checkoutState": "shipping_selected", + "paymentState": "cart", + "shippingState": "cart", + "tokenValue": "@string@", + "id": "@integer@", + "items": [ + { + "@id": "\/api\/v2\/shop\/order-items\/@integer@", + "@type": "OrderItem", + "variant": "\/api\/v2\/shop\/product-variants\/olivier_1_1", + "productName": "olivier_first_product", + "id": "@integer@", + "quantity": 3, + "unitPrice": 10, + "originalUnitPrice": 15, + "total": 30, + "discountedUnitPrice": 10, + "subtotal": 30 + }, + { + "@id": "\/api\/v2\/shop\/order-items\/@integer@", + "@type": "OrderItem", + "variant": "\/api\/v2\/shop\/product-variants\/bruce_1_1", + "productName": "bruce_first_product", + "id": "@integer@", + "quantity": 1, + "unitPrice": 11, + "originalUnitPrice": 16, + "total": 11, + "discountedUnitPrice": 11, + "subtotal": 11 + } + ], + "itemsTotal": 41, + "total": 51, + "taxTotal": 0, + "shippingTotal": 10, + "orderPromotionTotal": 0 +} \ No newline at end of file diff --git a/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/complete_checkout_response.json b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/complete_checkout_response.json new file mode 100644 index 0000000..6665a72 --- /dev/null +++ b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/complete_checkout_response.json @@ -0,0 +1,99 @@ +{ + "@context": "\/api\/v2\/contexts\/Order", + "@id": "\/api\/v2\/shop\/orders\/@string@", + "@type": "Order", + "shippingAddress": { + "@id": "\/api\/v2\/shop\/addresses\/@integer@", + "@type": "Address", + "firstName": "John", + "lastName": "Novak", + "countryCode": "PL", + "street": "Testowa 3", + "city": "Warszawa", + "postcode": "11-123" + }, + "billingAddress": { + "@id": "\/api\/v2\/shop\/addresses\/@integer@", + "@type": "Address", + "firstName": "John", + "lastName": "Novak", + "countryCode": "PL", + "street": "Testowa 3", + "city": "Warszawa", + "postcode": "11-123" + }, + "payments": [ + { + "@id": "\/api\/v2\/shop\/payments\/@integer@", + "@type": "Payment", + "id": "@integer@", + "method": "\/api\/v2\/shop\/payment-methods\/CASH_ON_DELIVERY" + } + ], + "shipments": [ + { + "@id": "\/api\/v2\/shop\/shipments\/@integer@", + "@type": "Shipment", + "id": "@integer@", + "method": "\/api\/v2\/shop\/shipping-methods\/ups", + "vendor": { + "@id": "\/api\/v2\/shop\/vendors\/@string@", + "@type": "Vendor", + "uuid": "@string@", + "slug": "oliver-queen-company" + } + }, + { + "@id": "\/api\/v2\/shop\/shipments\/@integer@", + "@type": "Shipment", + "id": "@integer@", + "method": "\/api\/v2\/shop\/shipping-methods\/fedex", + "vendor": { + "@id": "\/api\/v2\/shop\/vendors\/@string@", + "@type": "Vendor", + "uuid": "@string@", + "slug": "bruce-wayne-company" + } + } + ], + "currencyCode": "USD", + "localeCode": "en_US", + "checkoutState": "completed", + "paymentState": "awaiting_payment", + "shippingState": "ready", + "tokenValue": "@string@", + "id": "@integer@", + "items": [ + { + "@id": "\/api\/v2\/shop\/order-items\/@integer@", + "@type": "OrderItem", + "variant": "\/api\/v2\/shop\/product-variants\/olivier_1_1", + "productName": "olivier_first_product", + "id": "@integer@", + "quantity": 3, + "unitPrice": 10, + "originalUnitPrice": 15, + "total": 30, + "discountedUnitPrice": 10, + "subtotal": 30 + }, + { + "@id": "\/api\/v2\/shop\/order-items\/@integer@", + "@type": "OrderItem", + "variant": "\/api\/v2\/shop\/product-variants\/bruce_1_1", + "productName": "bruce_first_product", + "id": "@integer@", + "quantity": 1, + "unitPrice": 11, + "originalUnitPrice": 16, + "total": 11, + "discountedUnitPrice": 11, + "subtotal": 11 + } + ], + "itemsTotal": 41, + "total": 51, + "taxTotal": 0, + "shippingTotal": 10, + "orderPromotionTotal": 0 +} diff --git a/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/create_order_response.json b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/create_order_response.json new file mode 100644 index 0000000..cd9263b --- /dev/null +++ b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/create_order_response.json @@ -0,0 +1,8 @@ +{ + "@context": "\/api\/v2\/contexts\/Order", + "@id": "\/api\/v2\/shop\/orders\/@string@", + "@type": "Order", + "tokenValue": "@string@", + "id": "@integer@", + "itemsTotal": 0 +} \ No newline at end of file diff --git a/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/get_first_shipment_available_shipping_methods_response.json b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/get_first_shipment_available_shipping_methods_response.json new file mode 100644 index 0000000..4ca6c8b --- /dev/null +++ b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/get_first_shipment_available_shipping_methods_response.json @@ -0,0 +1,17 @@ +{ + "@context": "\/api\/v2\/contexts\/ShippingMethod", + "@id": "\/api\/v2\/shop\/orders\/@string@\/shipments\/@integer@\/methods", + "@type": "hydra:Collection", + "hydra:member": [ + { + "@id": "\/api\/v2\/shop\/shipping-methods\/ups", + "@type": "ShippingMethod", + "id": "@integer@", + "code": "ups", + "position": 0, + "name": "ups", + "price": 5 + } + ], + "hydra:totalItems": 1 +} \ No newline at end of file diff --git a/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/get_second_shipment_available_shipping_methods_response.json b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/get_second_shipment_available_shipping_methods_response.json new file mode 100644 index 0000000..dd50c6b --- /dev/null +++ b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/get_second_shipment_available_shipping_methods_response.json @@ -0,0 +1,26 @@ +{ + "@context": "\/api\/v2\/contexts\/ShippingMethod", + "@id": "\/api\/v2\/shop\/orders\/@string@\/shipments\/@integer@\/methods", + "@type": "hydra:Collection", + "hydra:member": [ + { + "@id": "\/api\/v2\/shop\/shipping-methods\/fedex", + "@type": "ShippingMethod", + "id": "@integer@", + "code": "fedex", + "position": 1, + "name": "fedex", + "price": 5 + }, + { + "@id": "\/api\/v2\/shop\/shipping-methods\/ups", + "@type": "ShippingMethod", + "id": "@integer@", + "code": "ups", + "position": 0, + "name": "ups", + "price": 5 + } + ], + "hydra:totalItems": 2 +} diff --git a/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/select_payment_method_response.json b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/select_payment_method_response.json new file mode 100644 index 0000000..db82cce --- /dev/null +++ b/OpenMarketplace/tests/End2End/Responses/Expected/CheckoutProcessEnd2EndTest/select_payment_method_response.json @@ -0,0 +1,99 @@ +{ + "@context": "\/api\/v2\/contexts\/Order", + "@id": "\/api\/v2\/shop\/orders\/@string@", + "@type": "Order", + "shippingAddress": { + "@id": "\/api\/v2\/shop\/addresses\/@integer@", + "@type": "Address", + "firstName": "John", + "lastName": "Novak", + "countryCode": "PL", + "street": "Testowa 3", + "city": "Warszawa", + "postcode": "11-123" + }, + "billingAddress": { + "@id": "\/api\/v2\/shop\/addresses\/@integer@", + "@type": "Address", + "firstName": "John", + "lastName": "Novak", + "countryCode": "PL", + "street": "Testowa 3", + "city": "Warszawa", + "postcode": "11-123" + }, + "payments": [ + { + "@id": "\/api\/v2\/shop\/payments\/@integer@", + "@type": "Payment", + "id": "@integer@", + "method": "\/api\/v2\/shop\/payment-methods\/CASH_ON_DELIVERY" + } + ], + "shipments": [ + { + "@id": "\/api\/v2\/shop\/shipments\/@integer@", + "@type": "Shipment", + "id": "@integer@", + "method": "\/api\/v2\/shop\/shipping-methods\/ups", + "vendor": { + "@id": "\/api\/v2\/shop\/vendors\/@string@", + "@type": "Vendor", + "uuid": "@string@", + "slug": "oliver-queen-company" + } + }, + { + "@id": "\/api\/v2\/shop\/shipments\/@integer@", + "@type": "Shipment", + "id": "@integer@", + "method": "\/api\/v2\/shop\/shipping-methods\/fedex", + "vendor": { + "@id": "\/api\/v2\/shop\/vendors\/@string@", + "@type": "Vendor", + "uuid": "@string@", + "slug": "bruce-wayne-company" + } + } + ], + "currencyCode": "USD", + "localeCode": "en_US", + "checkoutState": "payment_selected", + "paymentState": "cart", + "shippingState": "cart", + "tokenValue": "@string@", + "id": "@integer@", + "items": [ + { + "@id": "\/api\/v2\/shop\/order-items\/@integer@", + "@type": "OrderItem", + "variant": "\/api\/v2\/shop\/product-variants\/olivier_1_1", + "productName": "olivier_first_product", + "id": "@integer@", + "quantity": 3, + "unitPrice": 10, + "originalUnitPrice": 15, + "total": 30, + "discountedUnitPrice": 10, + "subtotal": 30 + }, + { + "@id": "\/api\/v2\/shop\/order-items\/@integer@", + "@type": "OrderItem", + "variant": "\/api\/v2\/shop\/product-variants\/bruce_1_1", + "productName": "bruce_first_product", + "id": "@integer@", + "quantity": 1, + "unitPrice": 11, + "originalUnitPrice": 16, + "total": 11, + "discountedUnitPrice": 11, + "subtotal": 11 + } + ], + "itemsTotal": 41, + "total": 51, + "taxTotal": 0, + "shippingTotal": 10, + "orderPromotionTotal": 0 +} \ No newline at end of file diff --git a/OpenMarketplace/tests/Functional/Api/ConversationTest.php b/OpenMarketplace/tests/Functional/Api/ConversationTest.php new file mode 100644 index 0000000..9057eb3 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Api/ConversationTest.php @@ -0,0 +1,139 @@ +entityManager = static::getContainer()->get('doctrine.orm.entity_manager'); + $this->orderRepository = $this->entityManager->getRepository(Order::class); + + $this->fixturesData = $this->loadFixturesFromFile('Api/ConversationTest/conversation.yml'); + } + + public function test_vendor_can_start_conversation(): void + { + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + $category = $this->fixturesData['peter_category']; + + $this->client->request('POST', '/api/v2/shop/account/vendor/conversations', [], [], $header, json_encode([ + 'category' => '/api/v2/shop/account/vendor/categories/' . $category->getId(), + 'messages' => [ + [ + 'content' => 'hello', + ], + ], + ])); + + $response = $this->client->getResponse(); + $this->assertEquals('hello', json_decode($response->getContent(), true)['messages'][0]['content']); + } + + public function test_vendor_can_reply_to_conversation(): void + { + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + $category = $this->fixturesData['peter_category']; + + $this->client->request('GET', '/api/v2/shop/account/vendor/conversations', [], [], $header, json_encode([ + 'category' => '/api/v2/shop/account/vendor/categories/' . $category->getId(), + ])); + + $response = $this->client->getResponse(); + $conversationIRI = json_decode($response->getContent(), true)['hydra:member'][0]['@id']; + + $this->client->request('PUT', $conversationIRI, [], [], $header, json_encode([ + 'messages' => [ + [ + 'content' => 'hello', + ], + ], + ])); + + $response = $this->client->getResponse(); + $this->assertEquals('hello', json_decode($response->getContent(), true)['messages'][1]['content']); + } + + public function test_vendor_cannot_reply_to_others_conversation(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/conversations', [], [], $header); + + $response = $this->client->getResponse(); + $conversationIRI = json_decode($response->getContent(), true)['hydra:member'][0]['@id']; + + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + $this->client->request('PUT', $conversationIRI, [], [], $header, json_encode([ + 'messages' => [ + [ + 'content' => 'hello', + ], + ], + ])); + $response = $this->client->getResponse(); + $this->assertResponseCode($response, 403); + } + + public function test_vendor_can_list_his_conversation(): void + { + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/conversations', [], [], $header); + + $response = $this->client->getResponse(); + $responseData = json_decode($response->getContent(), true); + $this->assertEquals($this->count($responseData['hydra:member']), 1); + $this->assertEquals($responseData['hydra:member'][0]['messages'][0]['content'], 'Own by Peter'); + } + + public function test_vendor_can_archive_his_conversation(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/conversations', [], [], $header); + + $response = $this->client->getResponse(); + $responseData = json_decode($response->getContent(), true); + $archiveIRI = $responseData['hydra:member'][1]['@id']; + + $this->client->request('PATCH', $archiveIRI . '/archive', [], [], $header); + $response = $this->client->getResponse(); + $responseData = json_decode($response->getContent(), true); + + $this->assertEquals($responseData['status'], 'closed'); + } + + public function test_validate_not_blank_category(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('POST', '/api/v2/shop/account/vendor/conversations', [], [], $header, json_encode([ + 'messages' => [ + [ + 'content' => 'hello', + ], + ], + ])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/VendorConversation/test_validate_not_blank_category_response', Response::HTTP_UNPROCESSABLE_ENTITY); + } +} diff --git a/OpenMarketplace/tests/Functional/Api/CustomerTest.php b/OpenMarketplace/tests/Functional/Api/CustomerTest.php new file mode 100644 index 0000000..82dfd58 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Api/CustomerTest.php @@ -0,0 +1,138 @@ +entityManager = static::getContainer()->get('doctrine.orm.entity_manager'); + $this->customerRepository = $this->entityManager->getRepository(Customer::class); + + $this->loadFixturesFromFile('Api/CustomerTest/customer.yml'); + } + + public function test_it_get_customers_by_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/customers', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/CustomerTest/test_it_get_customers_by_vendor', Response::HTTP_OK); + } + + public function test_it_get_customers_by_vendor_filter_email(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/customers', ['email' => 'john'], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/CustomerTest/test_it_get_customers_by_vendor_filter_email', Response::HTTP_OK); + } + + public function test_denies_access_get_orders_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/customers', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_get_customer_by_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var CustomerInterface $customer */ + $customer = $this->customerRepository->findOneBy(['email' => 'john.smith@example.com']); + + $this->client->request('GET', '/api/v2/shop/account/vendor/customers/' . $customer->getId(), [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/CustomerTest/test_it_get_customer_by_vendor', Response::HTTP_OK); + } + + public function test_not_found_get_customer_by_different_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + + /** @var CustomerInterface $customer */ + $customer = $this->customerRepository->findOneBy(['email' => 'john.smith@example.com']); + + $this->client->request('GET', '/api/v2/shop/account/vendor/customers/' . $customer->getId(), [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/not_found_response', Response::HTTP_NOT_FOUND); + } + + public function test_denies_access_get_customer_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + /** @var CustomerInterface $customer */ + $customer = $this->customerRepository->findOneBy(['email' => 'john.smith@example.com']); + + $this->client->request('GET', '/api/v2/shop/account/vendor/customers/' . $customer->getId(), [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_get_shop_customer_by_user(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + /** @var CustomerInterface $customer */ + $customer = $this->customerRepository->findOneBy(['email' => 'john.smith@example.com']); + + $this->client->request('GET', '/api/v2/shop/customers/' . $customer->getId(), [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/CustomerTest/test_get_shop_customer_by_user', Response::HTTP_OK); + } + + public function test_get_shop_customer_by_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var CustomerInterface $customer */ + $customer = $this->customerRepository->findOneBy(['email' => 'bruce.wayne@example.com']); + + $this->client->request('GET', '/api/v2/shop/customers/' . $customer->getId(), [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/CustomerTest/test_get_shop_customer_by_vendor', Response::HTTP_OK); + } + + public function test_get_shop_customer_by_different_user(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var CustomerInterface $customer */ + $customer = $this->customerRepository->findOneBy(['email' => 'john.smith@example.com']); + + $this->client->request('GET', '/api/v2/shop/customers/' . $customer->getId(), [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/not_found_response', Response::HTTP_NOT_FOUND); + } +} diff --git a/OpenMarketplace/tests/Functional/Api/DraftAttributeTest.php b/OpenMarketplace/tests/Functional/Api/DraftAttributeTest.php new file mode 100644 index 0000000..8f99f04 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Api/DraftAttributeTest.php @@ -0,0 +1,300 @@ +entityManager = static::getContainer()->get('doctrine.orm.entity_manager'); + $this->draftAttributeRepository = $this->entityManager->getRepository(DraftAttribute::class); + $this->draftAttributeTranslationRepository = $this->entityManager->getRepository(DraftAttributeTranslation::class); + + $this->loadFixturesFromFile('Api/DraftAttributeTest/draft_attribute.yml'); + } + + public function test_it_get_only_draft_attributes_for_current_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-draft/attributes', [], [], $header); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/DraftAttributeTest/test_it_get_only_draft_attributes_for_current_vendor_response', Response::HTTP_OK); + } + + public function test_it_prevents_to_get_different_vendor_draft_attribute(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var DraftAttributeInterface $draftAttribute */ + $draftAttribute = $this->draftAttributeRepository->findOneBy([ + 'code' => 'attribute_peter_1', + ]); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-draft/attributes/' . $draftAttribute->getUuid()->toString(), [], [], $header); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_prevents_to_get_attribute_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + /** @var DraftAttributeInterface $draftAttribute */ + $draftAttribute = $this->draftAttributeRepository->findOneBy([ + 'code' => 'attribute_peter_1', + ]); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-draft/attributes/' . $draftAttribute->getUuid()->toString(), [], [], $header); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_get_attribute_by_owner_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var DraftAttributeInterface $draftAttribute */ + $draftAttribute = $this->draftAttributeRepository->findOneBy([ + 'code' => 'attribute_bruce_1', + ]); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-draft/attributes/' . $draftAttribute->getUuid()->toString(), [], [], $header); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/DraftAttributeTest/test_it_get_attribute_by_owner_vendor_response', Response::HTTP_OK); + } + + public function test_it_prevents_creating_attribute_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + $this->client->request('POST', '/api/v2/shop/account/vendor/product-draft/attributes', [], [], $header, json_encode([ + 'code' => 'test', + 'type' => 'text', + 'storageType' => 'text', + 'position' => 1, + 'configuration' => [], + 'translations' => [ + 'en_US' => [ + 'locale' => 'en_US', + 'name' => 'test', + ], + ], + ])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_creating_attribute_by_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('POST', '/api/v2/shop/account/vendor/product-draft/attributes', [], [], $header, json_encode([ + 'code' => 'test', + 'type' => 'text', + 'storageType' => 'text', + 'position' => 1, + 'configuration' => [], + 'translations' => [ + 'en_US' => [ + 'locale' => 'en_US', + 'name' => 'test', + ], + ], + ])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/DraftAttributeTest/test_creating_attribute_by_vendor_response', Response::HTTP_CREATED); + } + + public function test_validate_not_blank_rules(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('POST', '/api/v2/shop/account/vendor/product-draft/attributes', [], [], $header, json_encode([ + 'code' => '', + 'type' => '', + 'storageType' => '', + 'translations' => [ + 'en_US' => [ + 'locale' => '', + 'name' => '', + ], + ], + ])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/DraftAttributeTest/test_validate_not_blank_rules_response', Response::HTTP_UNPROCESSABLE_ENTITY); + } + + public function test_it_prevents_update_attribute_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + /** @var DraftAttributeInterface $draftAttribute */ + $draftAttribute = $this->draftAttributeRepository->findOneBy([ + 'code' => 'attribute_bruce_1', + ]); + + $this->client->request('PUT', '/api/v2/shop/account/vendor/product-draft/attributes/' . $draftAttribute->getUuid()->toString(), [], [], $header, json_encode([ + 'configuration' => [ + 'min' => 2, + ], + ])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_prevents_update_attribute_by_different_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var DraftAttributeInterface $draftAttribute */ + $draftAttribute = $this->draftAttributeRepository->findOneBy([ + 'code' => 'attribute_peter_1', + ]); + + $this->client->request('PUT', '/api/v2/shop/account/vendor/product-draft/attributes/' . $draftAttribute->getUuid()->toString(), [], [], $header, json_encode([ + 'configuration' => [ + 'min' => 2, + ], + ])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_update_attribute_by_vendor_owner(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var DraftAttributeInterface $draftAttribute */ + $draftAttribute = $this->draftAttributeRepository->findOneBy([ + 'code' => 'attribute_bruce_1', + ]); + + $this->client->request('PUT', '/api/v2/shop/account/vendor/product-draft/attributes/' . $draftAttribute->getUuid()->toString(), [], [], $header, json_encode([ + 'configuration' => [ + 'min' => 2, + ], + ])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/DraftAttributeTest/test_it_update_attribute_by_vendor_owner_response', Response::HTTP_OK); + } + + public function test_it_update_attribute_translation_by_vendor_owner(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var DraftAttributeInterface $draftAttribute */ + $draftAttribute = $this->draftAttributeRepository->findOneBy([ + 'code' => 'attribute_bruce_1', + ]); + + /** @var DraftAttributeTranslationInterface $draftAttributeTranslation */ + $draftAttributeTranslation = $this->draftAttributeTranslationRepository->findOneBy([ + 'translatable' => $draftAttribute, + 'locale' => 'en_US', + 'name' => 'attribute_bruce_1_us', + ]); + + $this->client->request('PUT', '/api/v2/shop/account/vendor/product-draft/attribute-translations/' . $draftAttributeTranslation->getUuid()->toString(), [], [], $header, json_encode([ + 'name' => 'changed translation name', + ])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/DraftAttributeTest/test_it_update_attribute_translation_by_vendor_owner_response', Response::HTTP_OK); + } + + public function test_it_prevent_update_attribute_translation_by_other_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + + /** @var DraftAttributeInterface $draftAttribute */ + $draftAttribute = $this->draftAttributeRepository->findOneBy([ + 'code' => 'attribute_bruce_1', + ]); + + /** @var DraftAttributeTranslationInterface $draftAttributeTranslation */ + $draftAttributeTranslation = $this->draftAttributeTranslationRepository->findOneBy([ + 'translatable' => $draftAttribute, + 'locale' => 'en_US', + 'name' => 'attribute_bruce_1_us', + ]); + + $this->client->request('PUT', '/api/v2/shop/account/vendor/product-draft/attribute-translations/' . $draftAttributeTranslation->getUuid()->toString(), [], [], $header, json_encode([ + 'name' => 'changed translation name', + ])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_prevents_delete_attribute_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + /** @var DraftAttributeInterface $draftAttribute */ + $draftAttribute = $this->draftAttributeRepository->findOneBy([ + 'code' => 'attribute_peter_1', + ]); + + $this->client->request('DELETE', '/api/v2/shop/account/vendor/product-draft/attributes/' . $draftAttribute->getUuid()->toString(), [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_prevents_delete_attribute_by_different_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var DraftAttributeInterface $draftAttribute */ + $draftAttribute = $this->draftAttributeRepository->findOneBy([ + 'code' => 'attribute_peter_1', + ]); + + $this->client->request('DELETE', '/api/v2/shop/account/vendor/product-draft/attributes/' . $draftAttribute->getUuid()->toString(), [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_delete_attribute_by_owner_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var DraftAttributeInterface $draftAttribute */ + $draftAttribute = $this->draftAttributeRepository->findOneBy([ + 'code' => 'attribute_bruce_1', + ]); + + $this->client->request('DELETE', '/api/v2/shop/account/vendor/product-draft/attributes/' . $draftAttribute->getUuid()->toString(), [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponseCode($response, Response::HTTP_NO_CONTENT); + $this->assertEquals('', $response->getContent()); + } +} diff --git a/OpenMarketplace/tests/Functional/Api/OrderTest.php b/OpenMarketplace/tests/Functional/Api/OrderTest.php new file mode 100644 index 0000000..a03a1e7 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Api/OrderTest.php @@ -0,0 +1,176 @@ +entityManager = static::getContainer()->get('doctrine.orm.entity_manager'); + $this->orderRepository = $this->entityManager->getRepository(Order::class); + + $this->loadFixturesFromFile('Api/OrderTest/order.yml'); + } + + public function test_it_get_orders_by_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/orders', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/OrderTest/test_it_get_orders_by_vendor', Response::HTTP_OK); + } + + public function test_it_get_orders_by_vendor_filter_payment_state(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/orders', ['paymentState' => 'paid'], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/OrderTest/test_it_get_orders_by_vendor_filter_payment_state', Response::HTTP_OK); + } + + public function test_denies_access_get_orders_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/orders', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_get_order_by_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/orders/bruce_order_made_by_john_1', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/OrderTest/test_it_get_order_by_vendor', Response::HTTP_OK); + } + + public function test_forbidden_get_order_by_different_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/orders/bruce_order_made_by_john_1', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_denies_access_get_order_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/orders/bruce_order_made_by_john_1', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_cancel_order_by_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('PATCH', '/api/v2/shop/account/vendor/orders/bruce_order_made_by_john_2/cancel', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/OrderTest/test_it_cancel_order_by_vendor', Response::HTTP_OK); + } + + public function test_it_cancel_not_paid_order_by_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('PATCH', '/api/v2/shop/account/vendor/orders/bruce_order_made_by_john_1/cancel', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_cancel_order_by_different_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + + $this->client->request('PATCH', '/api/v2/shop/account/vendor/orders/bruce_order_made_by_john_2/cancel', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_cancel_order_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + $this->client->request('PATCH', '/api/v2/shop/account/vendor/orders/bruce_order_made_by_john_2/cancel', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_get_shop_orders_by_user(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + $this->client->request('GET', '/api/v2/shop/orders', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/OrderTest/test_get_shop_orders_by_shop_user', Response::HTTP_OK); + } + + public function test_get_shop_orders_by_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + + $this->client->request('GET', '/api/v2/shop/orders', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/OrderTest/test_get_shop_orders_by_vendor', Response::HTTP_OK); + } + + public function test_it_sets_paid_at_for_secondary_orders_when_primary_order_is_paid(): void + { + $header = $this->getHeaderForAdmin('clark.kent@example.com'); + /** @var OrderInterface $order */ + $order = $this->orderRepository->findOneBy(['tokenValue' => 'order_made_by_peter_main']); + foreach ($order->getSecondaryOrders() as $secondaryOrder) { + $this->assertNull($secondaryOrder->getPaidAt()); + } + $paymentId = $order->getLastPayment()->getId(); + + $this->client->request( + 'PATCH', + sprintf('/api/v2/admin/payments/%d/complete', $paymentId), + [], + [], + $header + ); + $this->assertResponseCode($this->client->getResponse(), 200); + + $order = $this->orderRepository->findOneBy(['tokenValue' => 'order_made_by_peter_main']); + + foreach ($order->getSecondaryOrders() as $secondaryOrder) { + $this->assertNotNull($secondaryOrder->getPaidAt()); + } + } +} diff --git a/OpenMarketplace/tests/Functional/Api/ProductDraftTest.php b/OpenMarketplace/tests/Functional/Api/ProductDraftTest.php new file mode 100644 index 0000000..69b2714 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Api/ProductDraftTest.php @@ -0,0 +1,65 @@ +entityManager = static::getContainer()->get('doctrine.orm.entity_manager'); + $this->productDraftRepository = $this->entityManager->getRepository(Draft::class); + + $this->loadFixturesFromFile('Api/ProductDraftTest/product_draft.yml'); + } + + public function test_it_get_by_current_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var Draft $productDraft */ + $productDraft = $this->productDraftRepository->findOneBy(['code' => 'product_draft_bruce_1']); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-drafts/' . $productDraft->getUuid()->toString(), [], [], $header); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/ProductDraftTest/test_it_get_by_current_vendor', Response::HTTP_OK); + } + + public function test_it_get_by_different_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + + /** @var Draft $productDraft */ + $productDraft = $this->productDraftRepository->findOneBy(['code' => 'product_draft_bruce_1']); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-drafts/' . $productDraft->getUuid()->toString(), [], [], $header); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_get_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + /** @var Draft $productDraft */ + $productDraft = $this->productDraftRepository->findOneBy(['code' => 'product_draft_bruce_1']); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-drafts/' . $productDraft->getUuid()->toString(), [], [], $header); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } +} diff --git a/OpenMarketplace/tests/Functional/Api/ProductListingTest.php b/OpenMarketplace/tests/Functional/Api/ProductListingTest.php new file mode 100644 index 0000000..8f5d2ac --- /dev/null +++ b/OpenMarketplace/tests/Functional/Api/ProductListingTest.php @@ -0,0 +1,421 @@ +entityManager = static::getContainer()->get('doctrine.orm.entity_manager'); + $this->productListingRepository = $this->entityManager->getRepository(Listing::class); + $this->taxonRepository = $this->entityManager->getRepository(Taxon::class); + $this->draftAttributeRepository = $this->entityManager->getRepository(DraftAttribute::class); + + $this->loadFixturesFromFile('Api/ProductListingTest/product_listings.yml'); + } + + public function test_it_gets_only_product_listings_for_current_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-listings', [], [], $header); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/ProductListingTest/test_it_gets_only_product_listings_for_current_vendor_response', Response::HTTP_OK); + } + + public function test_it_gets_only_product_listings_for_current_vendor_filter_by_verification_status(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-listings', ['verificationStatus' => 'verified'], [], $header); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/ProductListingTest/test_it_gets_only_product_listings_for_current_vendor_filter_by_verification_status', Response::HTTP_OK); + } + + public function test_it_gets_only_product_listings_for_current_vendor_filter_by_code(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-listings', ['code' => 'bruce_1'], [], $header); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/ProductListingTest/test_it_gets_only_product_listings_for_current_vendor_filter_by_code', Response::HTTP_OK); + } + + public function test_it_prevents_to_get_different_vendor_product_listing(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var Listing $productListing */ + $productListing = $this->productListingRepository->findOneBy([ + 'code' => 'product_listing_peter_1', + ]); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-listings/' . $productListing->getUuid(), [], [], $header); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_prevents_to_get_product_listing_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + /** @var Listing $productListing */ + $productListing = $this->productListingRepository->findOneBy([ + 'code' => 'product_listing_peter_1', + ]); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-listings/' . $productListing->getUuid(), [], [], $header); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_gets_product_listing_by_owner_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var Listing $productListing */ + $productListing = $this->productListingRepository->findOneBy([ + 'code' => 'product_listing_bruce_1', + ]); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-listings/' . $productListing->getUuid(), [], [], $header); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/ProductListingTest/test_it_gets_product_listing_by_owner_vendor_response', Response::HTTP_OK); + } + + public function test_it_prevents_creating_product_listing_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + $this->client->request('POST', '/api/v2/shop/account/vendor/product-listings', [], [], $header, json_encode([ + 'productDraft' => [ + 'code' => 'test', + 'images' => [], + 'translations' => [], + 'productListingPrices' => [], + 'attributes' => [], + 'productDraftTaxons' => [], + ], + ])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_creating_product_listing_by_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var Taxon $mainTaxon */ + $mainTaxon = $this->taxonRepository->findOneBy(['code' => 'CATEGORY']); + /** @var Taxon $additionalTaxon */ + $additionalTaxon = $this->taxonRepository->findOneBy(['code' => 'MUG']); + + /** @var DraftAttribute $draftAttribute */ + $draftAttribute = $this->draftAttributeRepository->findOneBy([ + 'code' => 'attribute_bruce_1', + ]); + + $this->client->request('POST', '/api/v2/shop/account/vendor/product-listings', [], [ + 'images' => [ + $this->getUploadedProductImageFile(), + ], + ], $header, json_encode([ + 'productDraft' => [ + 'code' => 'test', + 'translations' => [ + 'en_US' => [ + 'locale' => 'en_US', + 'name' => 'Test', + 'description' => 'Test description', + 'metaKeywords' => 'Test metaKeywords', + 'metaDescription' => 'Test metaDescription', + 'shortDescription' => 'Test shortDescription', + ], + ], + 'productListingPrices' => [ + [ + 'channelCode' => 'CODE', + 'price' => 100, + 'originalPrice' => 110, + 'minimumPrice' => 80, + ], + ], + 'attributes' => [ + [ + 'attribute' => '/api/v2/shop/account/vendor/product-draft/attributes/' . $draftAttribute->getUuid(), + 'value' => 'example text value', + ], + ], + 'mainTaxon' => '/api/v2/shop/taxons/' . $mainTaxon->getCode(), + 'productDraftTaxons' => [ + [ + 'taxon' => '/api/v2/shop/taxons/' . $additionalTaxon->getCode(), + 'position' => 2, + ], + ], + ], + ])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/ProductListingTest/test_creating_product_listing_by_vendor_response', Response::HTTP_CREATED); + } + + public function test_validates_not_blank_product_draft_when_creating_product_listing(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('POST', '/api/v2/shop/account/vendor/product-listings', [], [], $header, json_encode([])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/ProductListingTest/test_it_validates_not_blank_product_draft_response', Response::HTTP_UNPROCESSABLE_ENTITY); + } + + public function test_it_prevents_updating_product_listing_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + /** @var Listing $productListing */ + $productListing = $this->productListingRepository->findOneBy([ + 'code' => 'product_listing_bruce_1', + ]); + + $this->client->request('PUT', '/api/v2/shop/account/vendor/product-listings/' . $productListing->getUuid(), [], [], $header, json_encode([ + 'productDraft' => [ + 'images' => [], + 'translations' => [], + 'productListingPrices' => [], + 'attributes' => [], + 'productDraftTaxons' => [], + ], + ])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_prevents_updating_product_listing_by_other_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var Listing $productListing */ + $productListing = $this->productListingRepository->findOneBy([ + 'code' => 'product_listing_peter_1', + ]); + + $this->client->request('PUT', '/api/v2/shop/account/vendor/product-listings/' . $productListing->getUuid(), [], [], $header, json_encode([ + 'productDraft' => [ + 'images' => [], + 'translations' => [], + 'productListingPrices' => [], + 'attributes' => [], + 'productDraftTaxons' => [], + ], + ])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_update_product_listing_by_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var Listing $productListing */ + $productListing = $this->productListingRepository->findOneBy([ + 'code' => 'product_listing_bruce_1', + ]); + + /** @var Taxon $replacementMainTaxon */ + $replacementMainTaxon = $this->taxonRepository->findOneBy(['code' => 'SECOND_CATEGORY']); + + /** @var Taxon $replacementAdditionalTaxon */ + $replacementAdditionalTaxon = $this->taxonRepository->findOneBy(['code' => 'HAT']); + + /** @var DraftAttribute $draftAttribute */ + $draftAttribute = $this->draftAttributeRepository->findOneBy([ + 'code' => 'attribute_bruce_1', + ]); + + $this->client->request('PUT', '/api/v2/shop/account/vendor/product-listings/' . $productListing->getUuid(), [], [ + 'images' => [ + ], + ], $header, json_encode([ + 'productDraft' => [ + 'translations' => [ + 'en_US' => [ + 'locale' => 'en_US', + 'name' => 'Changed name', + 'slug' => 'Changed slug', + 'description' => 'Changed description', + 'metaKeywords' => 'Test metaKeywords', + 'metaDescription' => 'Test metaDescription', + 'shortDescription' => 'Test shortDescription', + ], + ], + 'productListingPrices' => [ + [ + 'channelCode' => 'CODE', + 'price' => 120, + 'originalPrice' => 110, + 'minimumPrice' => 115, + ], + ], + 'attributes' => [ + [ + 'attribute' => '/api/v2/shop/account/vendor/product-draft/attributes/' . $draftAttribute->getUuid(), + 'value' => 'changed value', + ], + ], + 'mainTaxon' => '/api/v2/shop/taxons/' . $replacementMainTaxon->getCode(), + 'productDraftTaxons' => [ + [ + 'taxon' => '/api/v2/shop/taxons/' . $replacementAdditionalTaxon->getCode(), + 'position' => 2, + ], + ], + ], + ])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/ProductListingTest/test_update_product_listing_by_vendor_response', Response::HTTP_OK); + } + + public function test_validates_not_blank_product_draft_when_updating_product_listing(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var Listing $productListing */ + $productListing = $this->productListingRepository->findOneBy([ + 'code' => 'product_listing_bruce_1', + ]); + + $this->client->request('PUT', '/api/v2/shop/account/vendor/product-listings/' . $productListing->getUuid(), [], [], $header, json_encode([])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/ProductListingTest/test_it_validates_not_blank_product_draft_response', Response::HTTP_UNPROCESSABLE_ENTITY); + } + + public function test_it_prevents_send_to_verification_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + /** @var Listing $productListing */ + $productListing = $this->productListingRepository->findOneBy([ + 'code' => 'product_listing_bruce_1', + ]); + + $this->client->request('PUT', sprintf('/api/v2/shop/account/vendor/product-listings/%s/send-to-verification', $productListing->getUuid()), [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_prevents_send_to_verification_by_different_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + + /** @var Listing $productListing */ + $productListing = $this->productListingRepository->findOneBy([ + 'code' => 'product_listing_bruce_1', + ]); + + $this->client->request('PUT', sprintf('/api/v2/shop/account/vendor/product-listings/%s/send-to-verification', $productListing->getUuid()), [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_send_to_verification_by_owner_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var Listing $productListing */ + $productListing = $this->productListingRepository->findOneBy([ + 'code' => 'product_listing_bruce_1', + ]); + + $this->client->request('PUT', sprintf('/api/v2/shop/account/vendor/product-listings/%s/send-to-verification', $productListing->getUuid()), [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/ProductListingTest/test_it_send_to_verification_by_owner_vendor', Response::HTTP_OK); + } + + public function test_it_prevents_delete_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + /** @var Listing $productListing */ + $productListing = $this->productListingRepository->findOneBy([ + 'code' => 'product_listing_bruce_1', + ]); + + $this->client->request('DELETE', '/api/v2/shop/account/vendor/product-listings/' . $productListing->getUuid(), [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_prevents_delete_by_different_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + + /** @var Listing $productListing */ + $productListing = $this->productListingRepository->findOneBy([ + 'code' => 'product_listing_bruce_1', + ]); + + $this->client->request('DELETE', '/api/v2/shop/account/vendor/product-listings/' . $productListing->getUuid(), [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_delete_by_owner_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var Listing $productListing */ + $productListing = $this->productListingRepository->findOneBy([ + 'code' => 'product_listing_bruce_1', + ]); + + $this->client->request('DELETE', '/api/v2/shop/account/vendor/product-listings/' . $productListing->getUuid(), [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponseCode($response, Response::HTTP_NO_CONTENT); + $this->assertEquals('', $response->getContent()); + } + + private function getUploadedProductImageFile(): UploadedFile + { + $fileName = 'product1.png'; + + $file = new UploadedFile( + $this->getFilePath($fileName), + $fileName, + 'image/png', + ); + + return $file; + } +} diff --git a/OpenMarketplace/tests/Functional/Api/ProductVariant/InventoryTest.php b/OpenMarketplace/tests/Functional/Api/ProductVariant/InventoryTest.php new file mode 100644 index 0000000..a68e8f9 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Api/ProductVariant/InventoryTest.php @@ -0,0 +1,130 @@ +entityManager = static::getContainer()->get('doctrine.orm.entity_manager'); + $this->vendorRepository = $this->entityManager->getRepository(Vendor::class); + + $this->loadFixturesFromFile('Api/ProductVariant/InventoryTest/inventory.yml'); + } + + public function test_it_get_product_variants_by_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-variants/inventory', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/ProductVariant/InventoryTest/test_it_get_product_variants_by_vendor', Response::HTTP_OK); + } + + public function test_denies_access_get_product_variants_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-variants/inventory', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_get_product_variant_by_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-variants/bruce_1_2/inventory', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/ProductVariant/InventoryTest/test_it_get_product_variant_by_vendor', Response::HTTP_OK); + } + + public function test_not_found_get_product_variant_by_different_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-variants/bruce_1_2/inventory', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_denies_access_get_product_variant_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + $this->client->request('GET', '/api/v2/shop/account/vendor/product-variants/bruce_1_2/inventory', [], [], $header); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_update_product_variant_by_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('PUT', '/api/v2/shop/account/vendor/product-variants/bruce_2_1/inventory', [], [], $header, json_encode([ + 'amount' => 5, + 'tracked' => true, + ], \JSON_THROW_ON_ERROR)); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/ProductVariant/InventoryTest/test_it_update_product_variant_by_vendor', Response::HTTP_OK); + } + + public function test_amount_validator_update_product_variant_by_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('PUT', '/api/v2/shop/account/vendor/product-variants/bruce_1_1/inventory', [], [], $header, json_encode([ + 'amount' => 1, + ], \JSON_THROW_ON_ERROR)); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/ProductVariant/InventoryTest/test_amount_validator_update_product_variant_by_vendor', Response::HTTP_UNPROCESSABLE_ENTITY); + } + + public function test_not_found_update_product_variant_by_different_vendor(): void + { + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + + $this->client->request('PUT', '/api/v2/shop/account/vendor/product-variants/bruce_2_1/inventory', [], [], $header, json_encode([ + 'amount' => 5, + 'tracked' => true, + ], \JSON_THROW_ON_ERROR)); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_denies_access_update_product_variant_by_user_without_vendor_context(): void + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + $this->client->request('PUT', '/api/v2/shop/account/vendor/product-variants/bruce_2_1/inventory', [], [], $header, json_encode([ + 'amount' => 5, + 'tracked' => true, + ], \JSON_THROW_ON_ERROR)); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } +} diff --git a/OpenMarketplace/tests/Functional/Api/VendorProfileTest.php b/OpenMarketplace/tests/Functional/Api/VendorProfileTest.php new file mode 100644 index 0000000..13141ea --- /dev/null +++ b/OpenMarketplace/tests/Functional/Api/VendorProfileTest.php @@ -0,0 +1,430 @@ +entityManager = static::getContainer()->get('doctrine.orm.entity_manager'); + $this->vendorRepository = $this->entityManager->getRepository(Vendor::class); + $this->customerRepository = $this->entityManager->getRepository(Customer::class); + $this->vendorImageRepository = $this->entityManager->getRepository(LogoImage::class); + $this->vendorBackgroundImageRepository = $this->entityManager->getRepository(BackgroundImage::class); + $this->loadFixturesFromFile('Api/VendorProfileTest/vendor_profile.yml'); + } + + public function test_customer_has_vendor_data() + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $customer = $this->customerRepository->findOneBy(['email' => 'bruce.wayne@example.com']); + + $this->client->request('GET', '/api/v2/shop/customers/' . $customer->getId(), [], [], $header); + $response = $this->client->getResponse(); + $data = json_decode($response->getContent(), true); + + $this->assertArrayHasKey('user', $data); + $this->assertEquals('Wayne-Enterprises-Inc', $data['user']['vendor']['slug']); + } + + public function test_it_get_shop_vendor_data_for_shop_user() + { + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + + $this->client->request('GET', '/api/v2/shop/vendors/' . $vendor->getUuid()->toString(), [], [], self::CONTENT_TYPE_HEADER); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/VendorProfileTest/test_it_get_shop_vendor_data_for_shop_user', Response::HTTP_OK); + } + + public function test_it_gets_vendor_data_for_shop_user_in_his_vendor_context() + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + + $this->client->request('GET', '/api/v2/shop/account/vendors/' . (string) $vendor->getUuid()->toString(), [], [], $header); + $response = $this->client->getResponse(); + + $this->assertResponse($response, 'Api/VendorProfileTest/test_it_gets_vendor_data_for_shop_user_in_his_vendor_context', Response::HTTP_OK); + } + + public function test_it_denies_access_on_get_vendor_data_when_shop_user_is_not_in_vendor_context() + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + + $this->client->request('GET', '/api/v2/shop/account/vendors/' . $vendor->getUuid()->toString(), [], [], $header); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_get_vendor_not_found_when_shop_user_has_different_vendor_context() + { + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + + $this->client->request('GET', '/api/v2/shop/account/vendors/' . $vendor->getUuid()->toString(), [], [], $header); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/not_found_response', Response::HTTP_NOT_FOUND); + } + + public function test_it_successful_update_vendor_data_for_shop_user_in_his_vendor_context() + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + + $this->client->request('PUT', '/api/v2/shop/account/vendors/' . $vendor->getUuid()->toString(), [], [], $header, json_encode([ + 'companyName' => 'Wayne Enterprises', + 'taxIdentifier' => '345', + 'bankAccountNumber' => 'PL14109024029586826934815556', + 'phoneNumber' => '123456789', + 'description' => 'Wayne Enterprises Desc', + 'vendorAddress' => [ + 'country' => '/api/v2/shop/countries/PL', + 'city' => 'New York', + 'street' => 'Wall St. 1', + 'postalCode' => '12123', + ], + ], \JSON_THROW_ON_ERROR)); + $response = $this->client->getResponse(); + + $this->assertEquals('Wayne-Enterprises', $vendor->getSlug()); + $this->assertResponse($response, 'Api/VendorProfileTest/test_it_successful_update_vendor_data_for_shop_user_in_his_vendor_context', Response::HTTP_OK); + } + + public function test_it_denies_access_on_update_vendor_when_shop_user_is_not_in_vendor_context() + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + + $this->client->request('PUT', '/api/v2/shop/account/vendors/' . $vendor->getUuid()->toString(), [], [], $header); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_update_vendor_not_found_when_shop_user_has_different_vendor_context() + { + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + + $this->client->request('PUT', '/api/v2/shop/account/vendors/' . $vendor->getUuid()->toString(), [], [], $header); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/not_found_response', Response::HTTP_NOT_FOUND); + } + + public function test_not_blank_validation_rules() + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + + $this->client->request('PUT', '/api/v2/shop/account/vendors/' . $vendor->getUuid()->toString(), [], [], $header, json_encode([ + 'companyName' => '', + 'taxIdentifier' => '', + 'bankAccountNumber' => '', + 'phoneNumber' => '', + 'description' => '', + 'vendorAddress' => [ + 'city' => '', + 'street' => '', + 'postalCode' => '', + ], + ])); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/VendorProfileTest/test_not_blank_validation_rules', Response::HTTP_UNPROCESSABLE_ENTITY); + } + + public function test_wrong_iri_for_country_error() + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + + $this->client->request('PUT', '/api/v2/shop/account/vendors/' . $vendor->getUuid()->toString(), [], [], $header, json_encode([ + 'vendorAddress' => [ + 'country' => 'PL', + ], + ])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/internal_server_error', Response::HTTP_INTERNAL_SERVER_ERROR); + } + + public function test_not_existed_country() + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + + $this->client->request('PUT', '/api/v2/shop/account/vendors/' . $vendor->getUuid()->toString(), [], [], $header, json_encode([ + 'vendorAddress' => [ + 'country' => '/api/v2/shop/countries/RO', + ], + ])); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/internal_server_error', Response::HTTP_INTERNAL_SERVER_ERROR); + } + + public function test_vendor_logo_upload_successfully() + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('POST', '/api/v2/shop/account/vendor/logo', [], [ + 'file' => $this->getUploadedFile(), + ], $header, json_encode([])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/VendorProfileTest/test_vendor_image_upload_successfully', Response::HTTP_CREATED); + } + + public function test_it_denies_access_on_logo_upload_from_user_without_vendor_context() + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + $this->client->request('POST', '/api/v2/shop/account/vendor/logo', [], [ + 'file' => $this->getUploadedFile(), + ], $header, json_encode([])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_not_blank_vendor_logo_file_validation_rule() + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + $this->client->request('POST', '/api/v2/shop/account/vendor/logo', [], [], $header, json_encode([])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/VendorProfileTest/test_not_blank_vendor_image_file_validation_rule', Response::HTTP_UNPROCESSABLE_ENTITY); + } + + public function test_it_denies_access_on_delete_vendor_logo_by_different_vendor() + { + $header = $this->getHeaderForLoginShopUser('bruce.wayne@example.com'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Weyland-Corp']); + /** @var LogoImage $vendorImage */ + $vendorImage = $this->vendorImageRepository->findOneBy(['owner' => $vendor]); + + $this->client->request('DELETE', '/api/v2/shop/account/vendor/logo/' . $vendorImage->getUuid()->toString(), [], [], $header); + $response = $this->client->getResponse(); + + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_denies_access_on_delete_vendor_logo_by_user_without_vendor_context() + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Weyland-Corp']); + /** @var LogoImage $vendorImage */ + $vendorImage = $this->vendorImageRepository->findOneBy(['owner' => $vendor]); + + $this->client->request('DELETE', '/api/v2/shop/account/vendor/logo/' . $vendorImage->getUuid()->toString(), [], [], $header); + $response = $this->client->getResponse(); + + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_deletes_vendor_logo_by_right_owner() + { + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Weyland-Corp']); + /** @var LogoImage $vendorImage */ + $vendorImage = $this->vendorImageRepository->findOneBy(['owner' => $vendor]); + + $this->client->request('DELETE', '/api/v2/shop/account/vendor/logo/' . $vendorImage->getUuid()->toString(), [], [], $header); + $response = $this->client->getResponse(); + + $this->assertResponseCode($response, Response::HTTP_NO_CONTENT); + $this->assertEmpty($response->getContent()); + } + + public function test_it_denies_access_on_delete_vendor_background_image_by_user_without_vendor_context() + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Weyland-Corp']); + /** @var BackgroundImage $vendorImage */ + $vendorImage = $this->vendorBackgroundImageRepository->findOneBy(['owner' => $vendor]); + + $this->client->request('DELETE', '/api/v2/shop/account/vendor/background-image/' . $vendorImage->getUuid()->toString(), [], [], $header); + $response = $this->client->getResponse(); + + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_deletes_vendor_background_image_by_right_owner() + { + $header = $this->getHeaderForLoginShopUser('peter.weyland@example.com'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Weyland-Corp']); + /** @var BackgroundImage $vendorImage */ + $vendorImage = $this->vendorBackgroundImageRepository->findOneBy(['owner' => $vendor]); + + $this->client->request('DELETE', '/api/v2/shop/account/vendor/background-image/' . $vendorImage->getUuid()->toString(), [], [], $header); + $response = $this->client->getResponse(); + + $this->assertResponseCode($response, Response::HTTP_NO_CONTENT); + $this->assertEmpty($response->getContent()); + } + + public function test_it_denies_access_on_background_image_upload_from_user_without_vendor_context() + { + $header = $this->getHeaderForLoginShopUser('john.smith@example.com'); + + $this->client->request('POST', '/api/v2/shop/account/vendor/background-image', [], [ + 'file' => $this->getUploadedFile(), + ], $header, json_encode([])); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/access_denied_response', Response::HTTP_FORBIDDEN); + } + + public function test_it_lists_vendors() + { + $header = $this->getHeaderForAdmin('clark.kent@example.com'); + + $this->client->request('GET', '/api/v2/admin/vendors', [], [], $header); + $response = $this->client->getResponse(); + + $readableResponse = json_decode($response->getContent(), true); + $this->assertCount(2, $readableResponse['hydra:member'], 'Number of listed vendors is invalid'); + } + + public function test_it_successful_update_vendor_data_by_admin() + { + $header = $this->getHeaderForAdmin('clark.kent@example.com'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + + $this->client->request('PUT', '/api/v2/admin/vendors/' . $vendor->getUuid()->toString(), [], [], $header, json_encode([ + 'companyName' => 'Wayne Enterprises', + 'taxIdentifier' => '345', + 'phoneNumber' => '123456789', + 'description' => 'Wayne Enterprises Desc', + 'vendorAddress' => [ + 'country' => '/api/v2/shop/countries/PL', + 'city' => 'New York', + 'street' => 'Wall St. 1', + 'postalCode' => '12123', + ], + ], \JSON_THROW_ON_ERROR)); + $response = $this->client->getResponse(); + $content = json_decode($response->getContent(), true); + $this->assertEquals('Wayne-Enterprises', $vendor->getSlug()); + $this->assertEquals($content['companyName'], 'Wayne Enterprises'); + } + + public function test_it_successful_enable_vendor_by_admin() + { + $header = $this->getHeaderForAdmin('clark.kent@example.com'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + + $this->client->request('PUT', '/api/v2/admin/vendors/' . $vendor->getUuid()->toString(), [], [], $header, json_encode([ + 'companyName' => 'Wayne Enterprises', + 'taxIdentifier' => '345', + 'phoneNumber' => '123456789', + 'description' => 'Wayne Enterprises Desc', + 'enabled' => true, + 'vendorAddress' => [ + 'country' => '/api/v2/shop/countries/PL', + 'city' => 'New York', + 'street' => 'Wall St. 1', + 'postalCode' => '12123', + ], + ], \JSON_THROW_ON_ERROR)); + $response = $this->client->getResponse(); + $content = json_decode($response->getContent(), true); + + $this->assertEquals('Wayne-Enterprises', $vendor->getSlug()); + $this->assertTrue($content['enabled']); + } + + public function test_it_successful_disable_vendor_by_admin() + { + $header = $this->getHeaderForAdmin('clark.kent@example.com'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + + $this->client->request('PUT', '/api/v2/admin/vendors/' . $vendor->getUuid()->toString(), [], [], $header, json_encode([ + 'companyName' => 'Wayne Enterprises', + 'taxIdentifier' => '345', + 'phoneNumber' => '123456789', + 'description' => 'Wayne Enterprises Desc', + 'enabled' => false, + 'vendorAddress' => [ + 'country' => '/api/v2/shop/countries/PL', + 'city' => 'New York', + 'street' => 'Wall St. 1', + 'postalCode' => '12123', + ], + ], \JSON_THROW_ON_ERROR)); + $response = $this->client->getResponse(); + $content = json_decode($response->getContent(), true); + + $this->assertEquals('Wayne-Enterprises', $vendor->getSlug()); + $this->assertFalse($content['enabled']); + } + + private function getUploadedFile(): UploadedFile + { + $fileName = 'avatar.png'; + + $file = new UploadedFile( + $this->getFilePath($fileName), + $fileName, + 'image/png', + ); + + return $file; + } +} diff --git a/OpenMarketplace/tests/Functional/Api/VendorRegistrationTest.php b/OpenMarketplace/tests/Functional/Api/VendorRegistrationTest.php new file mode 100644 index 0000000..1f22746 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Api/VendorRegistrationTest.php @@ -0,0 +1,224 @@ +loadFixturesFromFile('Api/VendorRegistrationTest/test_vendor_basic_registration.yml'); + + $loginData = $this->logInShopUser('test@example.com'); + $authorizationHeader = self::$container->getParameter('sylius.api.authorization_header'); + $header['HTTP_' . $authorizationHeader] = 'Bearer ' . $loginData; + $header = array_merge($header, self::CONTENT_TYPE_HEADER); + + $this->client->request('POST', '/api/v2/shop/account/vendor/register', [], [], $header, json_encode([ + 'companyName' => 'Wayland Corp', + 'taxIdentifier' => '345', + 'bankAccountNumber' => 'PL10109024026243964796978514', + 'phoneNumber' => '123456789', + 'description' => 'Wayland Corp Desc', + 'vendorAddress' => [ + 'country' => '/api/v2/shop/countries/PL', + 'city' => 'Warszawa', + 'street' => 'Jasna 1', + 'postalCode' => '12-123', + ], + ])); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/VendorRegistrationTest/success_registration_response', Response::HTTP_CREATED); + } + + public function test_vendor_unauthorized_registration() + { + $this->loadFixturesFromFile('Api/VendorRegistrationTest/test_vendor_basic_registration.yml'); + + $this->client->request('POST', '/api/v2/shop/account/vendor/register', [], [], self::CONTENT_TYPE_HEADER, json_encode([])); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/VendorRegistrationTest/unauthorized_registration_response', Response::HTTP_UNAUTHORIZED); + } + + public function test_existed_vendor_registration() + { + $this->loadFixturesFromFiles(['Api/VendorRegistrationTest/test_vendor_basic_registration.yml', 'Api/VendorRegistrationTest/test_existed_vendor_registration.yml']); + $loginData = $this->logInShopUser('test@example.com'); + $authorizationHeader = self::$container->getParameter('sylius.api.authorization_header'); + $header['HTTP_' . $authorizationHeader] = 'Bearer ' . $loginData; + $header = array_merge($header, self::CONTENT_TYPE_HEADER); + + $this->client->request('POST', '/api/v2/shop/account/vendor/register', [], [], $header, json_encode([ + 'companyName' => 'Wayland Corp', + 'taxIdentifier' => '345', + 'bankAccountNumber' => 'PL10109024026243964796978514', + 'phoneNumber' => '123456789', + 'description' => 'Wayland Corp Desc', + 'vendorAddress' => [ + 'country' => '/api/v2/shop/countries/PL', + 'city' => 'Warszawa', + 'street' => 'Jasna 1', + 'postalCode' => '12-123', + ], + ])); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/VendorRegistrationTest/existed_vendor_response', Response::HTTP_UNPROCESSABLE_ENTITY); + } + + public function test_not_blank_validation_rules() + { + $this->loadFixturesFromFile('Api/VendorRegistrationTest/test_vendor_basic_registration.yml'); + + $loginData = $this->logInShopUser('test@example.com'); + $authorizationHeader = self::$container->getParameter('sylius.api.authorization_header'); + $header['HTTP_' . $authorizationHeader] = 'Bearer ' . $loginData; + $header = array_merge($header, self::CONTENT_TYPE_HEADER); + + $this->client->request('POST', '/api/v2/shop/account/vendor/register', [], [], $header, json_encode([])); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/VendorRegistrationTest/not_blank_validation_errors_response', Response::HTTP_BAD_REQUEST); + } + + public function test_not_blank_address_fields_validation_rules() + { + $this->loadFixturesFromFile('Api/VendorRegistrationTest/test_vendor_basic_registration.yml'); + + $loginData = $this->logInShopUser('test@example.com'); + $authorizationHeader = self::$container->getParameter('sylius.api.authorization_header'); + $header['HTTP_' . $authorizationHeader] = 'Bearer ' . $loginData; + $header = array_merge($header, self::CONTENT_TYPE_HEADER); + + $this->client->request('POST', '/api/v2/shop/account/vendor/register', [], [], $header, json_encode([ + 'companyName' => 'Wayland Corp', + 'taxIdentifier' => '345', + 'bankAccountNumber' => 'PL10109024026243964796978514', + 'phoneNumber' => '123456789', + 'description' => 'Wayland Corp Desc', + 'vendorAddress' => [ + ], + ])); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/VendorRegistrationTest/not_blank_address_fields_validation_errors_response', Response::HTTP_UNPROCESSABLE_ENTITY); + } + + public function test_wrong_iri_for_country_error() + { + $this->loadFixturesFromFile('Api/VendorRegistrationTest/test_vendor_basic_registration.yml'); + + $loginData = $this->logInShopUser('test@example.com'); + $authorizationHeader = self::$container->getParameter('sylius.api.authorization_header'); + $header['HTTP_' . $authorizationHeader] = 'Bearer ' . $loginData; + $header = array_merge($header, self::CONTENT_TYPE_HEADER); + + $this->client->request('POST', '/api/v2/shop/account/vendor/register', [], [], $header, json_encode([ + 'companyName' => 'Wayland Corp', + 'taxIdentifier' => '345', + 'bankAccountNumber' => 'PL10109024026243964796978514', + 'phoneNumber' => '123456789', + 'description' => 'Wayland Corp Desc', + 'vendorAddress' => [ + 'country' => 'PL', + 'city' => 'Warszawa', + 'street' => 'Jasna 1', + 'postalCode' => '12-123', + ], + ])); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/internal_server_error', Response::HTTP_INTERNAL_SERVER_ERROR); + } + + public function test_not_existed_country() + { + $this->loadFixturesFromFile('Api/VendorRegistrationTest/test_vendor_basic_registration.yml'); + + $loginData = $this->logInShopUser('test@example.com'); + $authorizationHeader = self::$container->getParameter('sylius.api.authorization_header'); + $header['HTTP_' . $authorizationHeader] = 'Bearer ' . $loginData; + $header = array_merge($header, self::CONTENT_TYPE_HEADER); + + $this->client->request('POST', '/api/v2/shop/account/vendor/register', [], [], $header, json_encode([ + 'companyName' => 'Wayland Corp', + 'taxIdentifier' => '345', + 'bankAccountNumber' => 'PL10109024026243964796978514', + 'phoneNumber' => '123456789', + 'description' => 'Wayland Corp Desc', + 'vendorAddress' => [ + 'country' => '/api/v2/shop/countries/RO', + 'city' => 'Warszawa', + 'street' => 'Jasna 1', + 'postalCode' => '12-123', + ], + ])); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/internal_server_error', Response::HTTP_INTERNAL_SERVER_ERROR); + } + + public function test_min_length_validation_rules() + { + $this->loadFixturesFromFile('Api/VendorRegistrationTest/test_vendor_basic_registration.yml'); + + $loginData = $this->logInShopUser('test@example.com'); + $authorizationHeader = self::$container->getParameter('sylius.api.authorization_header'); + $header['HTTP_' . $authorizationHeader] = 'Bearer ' . $loginData; + $header = array_merge($header, self::CONTENT_TYPE_HEADER); + + $this->client->request('POST', '/api/v2/shop/account/vendor/register', [], [], $header, json_encode([ + 'companyName' => 'Wa', + 'taxIdentifier' => '34', + 'bankAccountNumber' => 'PL10109024026243964796978514', + 'phoneNumber' => '12', + 'description' => 'Wa', + 'vendorAddress' => [ + 'country' => '/api/v2/shop/countries/PL', + 'city' => 'Wa', + 'street' => 'Ja', + 'postalCode' => '12', + ], + ])); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/VendorRegistrationTest/min_length_validation_errors_response', Response::HTTP_UNPROCESSABLE_ENTITY); + } + + public function test_max_length_validation_rules() + { + $this->loadFixturesFromFile('Api/VendorRegistrationTest/test_vendor_basic_registration.yml'); + + $loginData = $this->logInShopUser('test@example.com'); + $authorizationHeader = self::getContainer()->getParameter('sylius.api.authorization_header'); + $header['HTTP_' . $authorizationHeader] = 'Bearer ' . $loginData; + $header = array_merge($header, self::CONTENT_TYPE_HEADER); + + $string256Length = str_repeat('a', 256); + $string2049Length = str_repeat('a', 2049); + + $this->client->request('POST', '/api/v2/shop/account/vendor/register', [], [], $header, json_encode([ + 'companyName' => $string256Length, + 'taxIdentifier' => $string256Length, + 'bankAccountNumber' => 'PL10109024026243964796978514', + 'phoneNumber' => $string256Length, + 'description' => $string2049Length, + 'vendorAddress' => [ + 'country' => '/api/v2/shop/countries/PL', + 'city' => $string256Length, + 'street' => $string256Length, + 'postalCode' => $string256Length, + ], + ])); + $response = $this->client->getResponse(); + $this->assertResponse($response, 'Api/VendorRegistrationTest/max_length_validation_errors_response', Response::HTTP_UNPROCESSABLE_ENTITY); + } +} diff --git a/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/ConversationTest/conversation.yml b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/ConversationTest/conversation.yml new file mode 100644 index 0000000..0607071 --- /dev/null +++ b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/ConversationTest/conversation.yml @@ -0,0 +1,139 @@ +Sylius\Component\Addressing\Model\Country: + country_pl: + code: 'PL' + country_us: + code: 'US' +Sylius\Component\Addressing\Model\Zone: + zone_us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_us: + code: 'US' + belongsTo: '@zone_us' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel: + code: "CODE" + name: "name" + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true +Sylius\Component\Core\Model\ShippingMethod: + shipping_method_ups: + code: 'ups' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: ['@channel'] + configuration: + CODE: + amount: 5 + shipping_method_fedex: + code: 'fedex' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: ['@channel'] + configuration: + CODE: + amount: 5 +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: "Bruce" + lastName: "Wayne" + email: "bruce.wayne@example.com" + emailCanonical: "bruce.wayne@example.com" + customer_peter: + firstName: "Peter" + lastName: "Weyland" + email: "peter.weyland@example.com" + emailCanonical: "peter.weyland@example.com" + customer_john: + firstName: "John" + lastName: "Smith" + email: "john.smith@example.com" + emailCanonical: "john.smith@example.com" + phoneNumber: 123456789 +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: "123password" + roles: ["ROLE_USER", "ROLE_VENDOR"] + enabled: "true" + customer: '@customer_bruce' + username: "bruce.wayne@example.com" + usernameCanonical: "bruce.wayne@example.com" + user_peter: + plainPassword: "123password" + roles: ["ROLE_USER", "ROLE_VENDOR"] + enabled: "true" + customer: '@customer_peter' + username: "peter.weyland@example.com" + usernameCanonical: "peter.weyland@example.com" + user_john: + plainPassword: "123password" + roles: ["ROLE_USER"] + enabled: "true" + customer: '@customer_john' + username: "john.smith@example.com" + usernameCanonical: "john.smith@example.com" +Sylius\Component\Core\Model\Address: + address_john: + firstName: "John" + lastName: "Smith" + countryCode: 'US' + city: 'Arkham City' + postcode: '00000' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL84109024022516138548468193' + phoneNumber: '555123123' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL11109024028914597692969454' + phoneNumber: '555444333' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Messaging\Entity\Conversation: + bruce_conversation: + shopUser: '@user_bruce' + peter_conversation: + category: '@peter_category' + shopUser: '@user_peter' + conversation_to_archive: + shopUser: '@user_bruce' +BitBag\OpenMarketplace\Component\Messaging\Entity\Message: + peter_message: + content: "Own by Peter" + conversation: '@peter_conversation' + bruce_message: + content: "Own by Bruce" + conversation: '@bruce_conversation' + archive_request: + content: '\ARCHIVE_REQUEST_MESSAGE' + conversation: "@conversation_to_archive" +BitBag\OpenMarketplace\Component\Messaging\Entity\Category: + peter_category: + name: "Category for Peter" diff --git a/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/CustomerTest/customer.yml b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/CustomerTest/customer.yml new file mode 100644 index 0000000..b1c4cb9 --- /dev/null +++ b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/CustomerTest/customer.yml @@ -0,0 +1,152 @@ +Sylius\Component\Addressing\Model\Country: + country_pl: + code: 'PL' + country_us: + code: 'US' +Sylius\Component\Addressing\Model\Zone: + zone_us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_us: + code: 'US' + belongsTo: '@zone_us' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel: + code: "CODE" + name: "name" + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true +Sylius\Component\Core\Model\ShippingMethod: + shipping_method_ups: + code: 'ups' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: ['@channel'] + configuration: + CODE: + amount: 5 + shipping_method_fedex: + code: 'fedex' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: ['@channel'] + configuration: + CODE: + amount: 5 +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: "Bruce" + lastName: "Wayne" + email: "bruce.wayne@example.com" + emailCanonical: "bruce.wayne@example.com" + customer_peter: + firstName: "Peter" + lastName: "Weyland" + email: "peter.weyland@example.com" + emailCanonical: "peter.weyland@example.com" + customer_john: + firstName: "John" + lastName: "Smith" + email: "john.smith@example.com" + emailCanonical: "john.smith@example.com" + phoneNumber: 123456789 + defaultAddress: '@address_john' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: "123password" + roles: ["ROLE_USER", "ROLE_VENDOR"] + enabled: "true" + customer: '@customer_bruce' + username: "bruce.wayne@example.com" + usernameCanonical: "bruce.wayne@example.com" + user_peter: + plainPassword: "123password" + roles: ["ROLE_USER", "ROLE_VENDOR"] + enabled: "true" + customer: '@customer_peter' + username: "peter.weyland@example.com" + usernameCanonical: "peter.weyland@example.com" + user_john: + plainPassword: "123password" + roles: ["ROLE_USER"] + enabled: "true" + customer: '@customer_john' + username: "john.smith@example.com" + usernameCanonical: "john.smith@example.com" +Sylius\Component\Core\Model\Address: + address_john: + firstName: "John" + lastName: "Smith" + countryCode: 'US' + city: 'Arkham City' + postcode: '00000' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL65109024029994763689555936' + phoneNumber: '555123123' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL19109024027219726634879744' + phoneNumber: '555444333' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Order\Entity\Order: + bruce_order_made_by_john_1: + currency_code: "USD" + locale_code: "en-US" + vendor: '@vendor_bruce' + customer: '@customer_john' + paymentState: "awaiting_payment" + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_1' + shippingAddress: '@address_john' + billingAddress: '@address_john' + mode: 'secondary' + bruce_order_made_by_john_2: + currency_code: "USD" + locale_code: "en-US" + vendor: '@vendor_bruce' + customer: '@customer_john' + paymentState: "paid" + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_2' + mode: 'secondary' + order_made_by_peter: + currency_code: "USD" + locale_code: "en-US" + vendor: '@vendor_bruce' + customer: '@customer_peter' + paymentState: "paid" + state: 'new' + checkoutState: 'completed' + tokenValue: 'order_made_by_peter' + mode: 'secondary' diff --git a/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/DraftAttributeTest/draft_attribute.yml b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/DraftAttributeTest/draft_attribute.yml new file mode 100644 index 0000000..7add089 --- /dev/null +++ b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/DraftAttributeTest/draft_attribute.yml @@ -0,0 +1,123 @@ +Sylius\Component\Addressing\Model\Country: + country_us: + code: 'US' +Sylius\Component\Addressing\Model\Zone: + zone_us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_us: + code: 'US' + belongsTo: '@zone_us' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel: + code: 'CODE' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' + customer_peter: + firstName: 'Peter' + lastName: 'Weyland' + email: 'peter.weyland@example.com' + emailCanonical: 'peter.weyland@example.com' + customer_john: + firstName: 'John' + lastName: 'Smith' + email: 'john.smith@example.com' + emailCanonical: 'john.smith@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: ['ROLE_USER', 'ROLE_VENDOR'] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + usernameCanonical: 'bruce.wayne@example.com' + user_peter: + plainPassword: '123password' + roles: ['ROLE_USER', 'ROLE_VENDOR'] + enabled: 'true' + customer: '@customer_peter' + username: 'peter.weyland@example.com' + usernameCanonical: 'peter.weyland@example.com' + user_john: + plainPassword: '123password' + roles: ['ROLE_USER'] + enabled: 'true' + customer: '@customer_john' + username: 'john.smith@example.com' + usernameCanonical: 'john.smith@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address_bruce: + country: '@country_us' + city: 'Arkham City' + postalCode: '00000' + street: 'Avenue 2115' + vendor_address_peter: + country: '@country_us' + city: 'San Francisco' + postalCode: '94016' + street: 'Unknown 1' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL31109024026812185484588836' + phoneNumber: '555123123' + vendorAddress: '@vendor_address_bruce' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL52109024028343758388462523' + phoneNumber: '555444333' + vendorAddress: '@vendor_address_peter' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttribute: + attribute_bruce_1: + vendor: '@vendor_bruce' + code: 'attribute_bruce_1' + type: 'text' + storageType: 'text' + translatable: 'true' + attribute_peter_1: + vendor: '@vendor_peter' + code: 'attribute_peter_1' + type: 'text' + storageType: 'text' + translatable: 'true' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttributeTranslation: + attribute_bruce_1_translations_us: + translatable: '@attribute_bruce_1' + locale: 'en_US' + name: 'attribute_bruce_1_us' + attribute_peter_1_translations_us: + translatable: '@attribute_peter_1' + locale: 'en_US' + name: 'attribute_peter_1_us' diff --git a/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/OrderTest/order.yml b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/OrderTest/order.yml new file mode 100644 index 0000000..cdacf22 --- /dev/null +++ b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/OrderTest/order.yml @@ -0,0 +1,333 @@ +Sylius\Component\Addressing\Model\Country: + country_pl: + code: 'PL' + country_us: + code: 'US' +Sylius\Component\Addressing\Model\Zone: + zone_us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_us: + code: 'US' + belongsTo: '@zone_us' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel: + code: "CODE" + name: "name" + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true +Sylius\Component\Core\Model\ShippingMethod: + shipping_method_ups: + code: 'ups' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: ['@channel'] + configuration: + CODE: + amount: 5 + shipping_method_fedex: + code: 'fedex' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: ['@channel'] + configuration: + CODE: + amount: 5 +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: "Bruce" + lastName: "Wayne" + email: "bruce.wayne@example.com" + emailCanonical: "bruce.wayne@example.com" + customer_peter: + firstName: "Peter" + lastName: "Weyland" + email: "peter.weyland@example.com" + emailCanonical: "peter.weyland@example.com" + customer_john: + firstName: "John" + lastName: "Smith" + email: "john.smith@example.com" + emailCanonical: "john.smith@example.com" + phoneNumber: 123456789 +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: "123password" + roles: ["ROLE_USER", "ROLE_VENDOR"] + enabled: "true" + customer: '@customer_bruce' + username: "bruce.wayne@example.com" + usernameCanonical: "bruce.wayne@example.com" + user_peter: + plainPassword: "123password" + roles: ["ROLE_USER", "ROLE_VENDOR"] + enabled: "true" + customer: '@customer_peter' + username: "peter.weyland@example.com" + usernameCanonical: "peter.weyland@example.com" + user_john: + plainPassword: "123password" + roles: ["ROLE_USER"] + enabled: "true" + customer: '@customer_john' + username: "john.smith@example.com" + usernameCanonical: "john.smith@example.com" +Sylius\Component\Core\Model\AdminUser: + test_admin: + enabled: true + username: "Clark Kent" + firstName: "Clark" + lastName: "Kent" + email: "clark.kent@example.com" + emailCanonical: "clark.kent@example.com" + localeCode: 'en_US' + roles: ["ROLE_ADMINISTRATION_ACCESS","ROLE_API_ACCESS"] +Sylius\Component\Core\Model\Address: + address_john: + firstName: "John" + lastName: "Smith" + countryCode: 'US' + city: 'Arkham City' + postcode: '00000' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL31109024026812185484588836' + phoneNumber: '555123123' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL17109024022586255711928552' + phoneNumber: '555444333' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + product_bruce_1: + vendor: '@vendor_bruce' + code: "bruce_1" + enabled: true + channels: ['@channel'] + product_peter_1: + vendor: '@vendor_peter' + code: "peter_2" + enabled: true + channels: [ '@channel' ] +Sylius\Component\Core\Model\ProductVariant: + product_variant_product_bruce_1_1: + product: '@product_bruce_1' + code: "bruce_1_1" + enabled: true + onHold: 2 + onHand: 3 + tracked: true + product_variant_product_bruce_1_2: + product: '@product_bruce_1' + code: "bruce_1_2" + enabled: true + onHand: 1 + tracked: true + product_variant_product_peter_1_1: + product: '@product_peter_1' + code: "peter_1_1" + enabled: true + onHand: 3 + tracked: true +Sylius\Component\Core\Model\ChannelPricing: + pricing_product_variant_product_bruce_1_1: + price: 10 + originalPrice: 15 + minimumPrice: 0 + channelCode: 'CODE' + productVariant: '@product_variant_product_bruce_1_1' + pricing_product_variant_product_bruce_1_2: + price: 13 + originalPrice: 25 + minimumPrice: 10 + channelCode: 'CODE' + productVariant: '@product_variant_product_bruce_1_2' + pricing_product_variant_product_peter_1_1: + price: 9 + originalPrice: 12 + minimumPrice: 5 + channelCode: 'CODE' + productVariant: '@product_variant_product_peter_1_1' +BitBag\OpenMarketplace\Component\Order\Entity\Order: + bruce_order_made_by_john_1_main: + mode: "primary" + currency_code: "USD" + locale_code: "en-US" + customer: '@customer_john' + paymentState: "awaiting_payment" + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_1_main' + bruce_order_made_by_john_1: + primaryOrder: '@bruce_order_made_by_john_1_main' + mode: "secondary" + currency_code: "USD" + locale_code: "en-US" + vendor: '@vendor_bruce' + customer: '@customer_john' + paymentState: "awaiting_payment" + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_1' + shippingAddress: '@address_john' + billingAddress: '@address_john' + bruce_order_made_by_john_2_main: + mode: "primary" + currency_code: "USD" + locale_code: "en-US" + customer: '@customer_john' + paymentState: "paid" + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_2_main' + bruce_order_made_by_john_2: + primaryOrder: '@bruce_order_made_by_john_2_main' + mode: "secondary" + currency_code: "USD" + locale_code: "en-US" + vendor: '@vendor_bruce' + customer: '@customer_john' + paymentState: "paid" + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_2' + peter_order_made_by_john_main: + mode: "primary" + currency_code: "USD" + locale_code: "en-US" + customer: '@customer_john' + paymentState: "paid" + state: 'new' + checkoutState: 'completed' + tokenValue: 'peter_order_made_by_john_main' + peter_order_made_by_john: + primaryOrder: '@peter_order_made_by_john' + mode: "secondary" + currency_code: "USD" + locale_code: "en-US" + vendor: '@vendor_peter' + customer: '@customer_john' + paymentState: "paid" + state: 'new' + checkoutState: 'completed' + tokenValue: 'peter_order_made_by_john' + order_made_by_peter_main: + mode: "primary" + currency_code: "USD" + locale_code: "en-US" + customer: '@customer_peter' + paymentState: "paid" + state: 'new' + checkoutState: 'completed' + tokenValue: 'order_made_by_peter_main' + order_made_by_peter_1: + primaryOrder: '@order_made_by_peter_main' + mode: "secondary" + currency_code: "USD" + locale_code: "en-US" + customer: '@customer_peter' + paymentState: "awaiting_payment" + state: 'new' + checkoutState: 'completed' + tokenValue: 'order_made_by_peter_1' + order_made_by_peter_2: + primaryOrder: '@order_made_by_peter_main' + mode: "secondary" + currency_code: "USD" + locale_code: "en-US" + customer: '@customer_peter' + paymentState: "awaiting_payment" + state: 'new' + checkoutState: 'completed' + tokenValue: 'order_made_by_peter_2' +BitBag\OpenMarketplace\Component\Order\Entity\OrderItem: + bruce_order_made_by_john_1_item_1: + order: '@bruce_order_made_by_john_1' + variant: '@product_variant_product_bruce_1_1' + bruce_order_made_by_john_2_item_1: + order: '@bruce_order_made_by_john_2' + variant: '@product_variant_product_bruce_1_2' + peter_order_made_by_john_1_item_1: + order: '@peter_order_made_by_john' + variant: '@product_variant_product_peter_1_1' +BitBag\OpenMarketplace\Component\Order\Entity\Shipment: + bruce_order_made_by_john_1_shipment: + vendor: '@vendor_bruce' + order: '@bruce_order_made_by_john_1' + method: '@shipping_method_ups' + bruce_order_made_by_john_2_shipment: + vendor: '@vendor_bruce' + order: '@bruce_order_made_by_john_2' + method: '@shipping_method_fedex' + peter_order_made_by_john_shipment: + vendor: '@vendor_peter' + order: '@peter_order_made_by_john' + method: '@shipping_method_ups' +Sylius\Component\Core\Model\OrderItemUnit: + bruce_order_made_by_john_1_item_1_unit: + __construct: ["@bruce_order_made_by_john_1_item_1"] + shipment: '@bruce_order_made_by_john_1_shipment' +Sylius\Component\Core\Model\PaymentMethod: + payment_method_cash_on_delivery: + code: 'CASH_ON_DELIVERY' + enabled: true + gatewayConfig: '@gateway_offline' + currentLocale: 'en_US' + translations: + - '@payment_method_cash_on_delivery_translation' + channels: ['@channel'] +Sylius\Component\Payment\Model\PaymentMethodTranslation: + payment_method_cash_on_delivery_translation: + name: 'Cash on delivery' + locale: 'en_US' + description: '' + translatable: '@payment_method_cash_on_delivery' +Sylius\Bundle\PayumBundle\Model\GatewayConfig: + gateway_offline: + gatewayName: 'Offline' + factoryName: 'offline' + config: [] +Sylius\Component\Core\Model\Payment: + peter_order_payment_main: + order: "@order_made_by_peter_main" + method: "@payment_method_cash_on_delivery" + currencyCode: "USD" + state: "new" + peter_order_payment_1: + order: "@order_made_by_peter_1" + method: "@payment_method_cash_on_delivery" + currencyCode: "USD" + state: "new" + peter_order_payment_2: + order: "@order_made_by_peter_2" + method: "@payment_method_cash_on_delivery" + currencyCode: "USD" + state: "new" diff --git a/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/ProductDraftTest/product_draft.yml b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/ProductDraftTest/product_draft.yml new file mode 100644 index 0000000..7e94824 --- /dev/null +++ b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/ProductDraftTest/product_draft.yml @@ -0,0 +1,262 @@ +Sylius\Component\Addressing\Model\Country: + country_us: + code: 'US' +Sylius\Component\Addressing\Model\Zone: + zone_us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_us: + code: 'US' + belongsTo: '@zone_us' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: "" + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel: + code: 'CODE' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' + customer_peter: + firstName: 'Peter' + lastName: 'Weyland' + email: 'peter.weyland@example.com' + emailCanonical: 'peter.weyland@example.com' + customer_john: + firstName: 'John' + lastName: 'Smith' + email: 'john.smith@example.com' + emailCanonical: 'john.smith@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: ['ROLE_USER', 'ROLE_VENDOR'] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + usernameCanonical: 'bruce.wayne@example.com' + user_peter: + plainPassword: '123password' + roles: ['ROLE_USER', 'ROLE_VENDOR'] + enabled: 'true' + customer: '@customer_peter' + username: 'peter.weyland@example.com' + usernameCanonical: 'peter.weyland@example.com' + user_john: + plainPassword: '123password' + roles: ['ROLE_USER'] + enabled: 'true' + customer: '@customer_john' + username: 'john.smith@example.com' + usernameCanonical: 'john.smith@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address_bruce: + country: '@country_us' + city: 'Arkham City' + postalCode: '00000' + street: 'Avenue 2115' + vendor_address_peter: + country: '@country_us' + city: 'San Francisco' + postalCode: '94016' + street: 'Unknown 1' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL31109024026812185484588836' + phoneNumber: '555123123' + vendorAddress: '@vendor_address_bruce' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL17109024022586255711928552' + phoneNumber: '555444333' + vendorAddress: '@vendor_address_peter' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttribute: + attribute_bruce_1: + vendor: '@vendor_bruce' + code: 'attribute_bruce_1' + type: 'text' + storageType: 'text' + translatable: 'true' + attribute_bruce_2: + vendor: '@vendor_bruce' + code: 'attribute_bruce_2' + type: 'text' + storageType: 'text' + translatable: 'true' + attribute_peter_1: + vendor: '@vendor_peter' + code: 'attribute_peter_1' + type: 'text' + storageType: 'text' + translatable: 'true' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttributeTranslation: + attribute_bruce_1_translations_us: + translatable: '@attribute_bruce_1' + locale: 'en_US' + name: 'attribute_bruce_1_us' + attribute_bruce_2_translations_us: + translatable: '@attribute_bruce_2' + locale: 'en_US' + name: 'attribute_bruce_2_us' + attribute_peter_1_translations_us: + translatable: '@attribute_peter_1' + locale: 'en_US' + name: 'attribute_peter_1_us' +BitBag\OpenMarketplace\Component\ProductListing\Entity\Listing: + product_listing_bruce_1: + code: 'product_listing_bruce_1' + vendor: '@vendor_bruce' + product_listing_bruce_2: + code: 'product_listing_bruce_2' + vendor: '@vendor_bruce' + verificationStatus: 'verified' + product_listing_peter_1: + code: 'product_listing_peter_1' + vendor: '@vendor_peter' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftImage: + product_draft_image_bruce_1: + owner: '@product_draft_bruce_1' + path: '/dummy/file/path' +BitBag\OpenMarketplace\Component\ProductListing\Entity\Draft: + product_draft_bruce_1: + code: 'product_draft_bruce_1' + productListing: '@product_listing_bruce_1' + images: ['@product_draft_image_bruce_1'] + productListingPrices: ['@product_draft_listing_price_bruce_1'] + attributes: ['@product_draft_attribute_value_bruce_1'] + mainTaxon: '@category_taxon' + productDraftTaxons: ['@product_draft_taxon_bruce_1'] + product_draft_bruce_2: + code: 'product_draft_bruce_2' + productListing: '@product_listing_bruce_2' + productListingPrices: ['@product_draft_listing_price_bruce_2'] + attributes: ['@product_draft_attribute_value_bruce_2'] + mainTaxon: '@category_taxon' + productDraftTaxons: ['@product_draft_taxon_bruce_2'] + product_draft_peter_1: + code: 'product_draft_peter_1' + productListing: '@product_listing_peter_1' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftTranslation: + product_draft_bruce_1_translations_us: + productDraft: '@product_draft_bruce_1' + locale: 'en_US' + name: 'product_draft_bruce_1_translations_us' + slug: 'product_draft_bruce_1_translations_us' + product_draft_bruce_2_translations_us: + productDraft: '@product_draft_bruce_2' + locale: 'en_US' + name: 'product_draft_bruce_2_translations_us' + slug: 'product_draft_bruce_2_translations_us' + product_draft_peter_1_translations_us: + productDraft: '@product_draft_peter_1' + locale: 'en_US' + name: 'product_draft_peter_1_translations_us' + slug: 'product_draft_peter_1_translations_us' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttributeValue: + product_draft_attribute_value_bruce_1: + draft: '@product_draft_bruce_1' + attribute: '@attribute_bruce_1' + value: 'example value' + product_draft_attribute_value_bruce_2: + draft: '@product_draft_bruce_2' + attribute: '@attribute_bruce_2' + value: 'example value' +BitBag\OpenMarketplace\Component\ProductListing\Entity\ListingPrice: + product_draft_listing_price_bruce_1: + productDraft: '@product_draft_bruce_1' + price: 100 + originalPrice: 80 + minimumPrice: 90 + channelCode: 'CODE' + product_draft_listing_price_bruce_2: + productDraft: '@product_draft_bruce_2' + price: 150 + originalPrice: 200 + minimumPrice: 90 + channelCode: 'CODE' +Sylius\Component\Core\Model\Taxon: + category_taxon: + code: 'CATEGORY' + currentLocale: 'en_US' + translations: ['@en_us_category_translation'] + children: ['@mug_taxon', '@hat_taxon'] + second_category_taxon: + code: 'SECOND_CATEGORY' + currentLocale: 'en_US' + translations: ['@en_us_second_category_translation'] + children: ['@hat_taxon'] + mug_taxon: + code: 'MUG' + currentLocale: 'en_US' + translations: ['@en_us_mug_taxon_translation'] + parent: '@category_taxon' + position: 0 + hat_taxon: + code: 'HAT' + currentLocale: 'en_US' + translations: ['@en_us_hat_translation'] + parent: '@category_taxon' + position: 1 +Sylius\Component\Taxonomy\Model\TaxonTranslation: + en_us_category_translation: + slug: 'categories' + locale: 'en_US' + name: 'Categories' + description: 'Some description Lorem ipsum dolor sit amet.' + translatable: '@category_taxon' + en_us_second_category_translation: + slug: 'second-categories' + locale: 'en_US' + name: 'Second categories' + description: 'Some description Lorem ipsum dolor sit amet.' + translatable: '@second_category_taxon' + en_us_mug_taxon_translation: + slug: 'categories/mugs' + locale: 'en_US' + name: 'Mugs' + description: 'Some description Lorem ipsum dolor sit amet.' + translatable: '@mug_taxon' + en_us_hat_translation: + slug: 'categories/hats' + locale: 'en_US' + name: 'Hats' + description: 'Some description Lorem ipsum dolor sit amet.' + translatable: '@hat_taxon' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftTaxon: + product_draft_taxon_bruce_1: + productDraft: '@product_draft_bruce_1' + taxon: '@mug_taxon' + position: 1 + product_draft_taxon_bruce_2: + productDraft: '@product_draft_bruce_2' + taxon: '@hat_taxon' + position: 2 diff --git a/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/ProductListingTest/product_listings.yml b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/ProductListingTest/product_listings.yml new file mode 100644 index 0000000..63fa271 --- /dev/null +++ b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/ProductListingTest/product_listings.yml @@ -0,0 +1,258 @@ +Sylius\Component\Addressing\Model\Country: + country_us: + code: 'US' +Sylius\Component\Addressing\Model\Zone: + zone_us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_us: + code: 'US' + belongsTo: '@zone_us' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: "" + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel: + code: 'CODE' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' + customer_peter: + firstName: 'Peter' + lastName: 'Weyland' + email: 'peter.weyland@example.com' + emailCanonical: 'peter.weyland@example.com' + customer_john: + firstName: 'John' + lastName: 'Smith' + email: 'john.smith@example.com' + emailCanonical: 'john.smith@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: ['ROLE_USER', 'ROLE_VENDOR'] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + usernameCanonical: 'bruce.wayne@example.com' + user_peter: + plainPassword: '123password' + roles: ['ROLE_USER', 'ROLE_VENDOR'] + enabled: 'true' + customer: '@customer_peter' + username: 'peter.weyland@example.com' + usernameCanonical: 'peter.weyland@example.com' + user_john: + plainPassword: '123password' + roles: ['ROLE_USER'] + enabled: 'true' + customer: '@customer_john' + username: 'john.smith@example.com' + usernameCanonical: 'john.smith@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address_bruce: + country: '@country_us' + city: 'Arkham City' + postalCode: '00000' + street: 'Avenue 2115' + vendor_address_peter: + country: '@country_us' + city: 'San Francisco' + postalCode: '94016' + street: 'Unknown 1' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL31109024026812185484588836' + phoneNumber: '555123123' + vendorAddress: '@vendor_address_bruce' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL17109024022586255711928552' + phoneNumber: '555444333' + vendorAddress: '@vendor_address_peter' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttribute: + attribute_bruce_1: + vendor: '@vendor_bruce' + code: 'attribute_bruce_1' + type: 'text' + storageType: 'text' + translatable: 'true' + attribute_bruce_2: + vendor: '@vendor_bruce' + code: 'attribute_bruce_2' + type: 'text' + storageType: 'text' + translatable: 'true' + attribute_peter_1: + vendor: '@vendor_peter' + code: 'attribute_peter_1' + type: 'text' + storageType: 'text' + translatable: 'true' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttributeTranslation: + attribute_bruce_1_translations_us: + translatable: '@attribute_bruce_1' + locale: 'en_US' + name: 'attribute_bruce_1_us' + attribute_bruce_2_translations_us: + translatable: '@attribute_bruce_2' + locale: 'en_US' + name: 'attribute_bruce_2_us' + attribute_peter_1_translations_us: + translatable: '@attribute_peter_1' + locale: 'en_US' + name: 'attribute_peter_1_us' +BitBag\OpenMarketplace\Component\ProductListing\Entity\Listing: + product_listing_bruce_1: + code: 'product_listing_bruce_1' + vendor: '@vendor_bruce' + product_listing_bruce_2: + code: 'product_listing_bruce_2' + vendor: '@vendor_bruce' + verificationStatus: 'verified' + product_listing_peter_1: + code: 'product_listing_peter_1' + vendor: '@vendor_peter' +BitBag\OpenMarketplace\Component\ProductListing\Entity\Draft: + product_draft_bruce_1: + code: 'product_draft_bruce_1' + productListing: '@product_listing_bruce_1' + productListingPrices: ['@product_draft_listing_price_bruce_1'] + attributes: ['@product_draft_attribute_value_bruce_1'] + mainTaxon: '@category_taxon' + productDraftTaxons: ['@product_draft_taxon_bruce_1'] + status: "created" + product_draft_bruce_2: + code: 'product_draft_bruce_2' + productListing: '@product_listing_bruce_2' + productListingPrices: ['@product_draft_listing_price_bruce_2'] + attributes: ['@product_draft_attribute_value_bruce_2'] + mainTaxon: '@category_taxon' + productDraftTaxons: ['@product_draft_taxon_bruce_2'] + product_draft_peter_1: + code: 'product_draft_peter_1' + productListing: '@product_listing_peter_1' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftTranslation: + product_draft_bruce_1_translations_us: + productDraft: '@product_draft_bruce_1' + locale: 'en_US' + name: 'product_draft_bruce_1_translations_us' + slug: 'product_draft_bruce_1_translations_us' + product_draft_bruce_2_translations_us: + productDraft: '@product_draft_bruce_2' + locale: 'en_US' + name: 'product_draft_bruce_2_translations_us' + slug: 'product_draft_bruce_2_translations_us' + product_draft_peter_1_translations_us: + productDraft: '@product_draft_peter_1' + locale: 'en_US' + name: 'product_draft_peter_1_translations_us' + slug: 'product_draft_peter_1_translations_us' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttributeValue: + product_draft_attribute_value_bruce_1: + draft: '@product_draft_bruce_1' + attribute: '@attribute_bruce_1' + value: 'example value' + product_draft_attribute_value_bruce_2: + draft: '@product_draft_bruce_2' + attribute: '@attribute_bruce_2' + value: 'example value' +BitBag\OpenMarketplace\Component\ProductListing\Entity\ListingPrice: + product_draft_listing_price_bruce_1: + productDraft: '@product_draft_bruce_1' + price: 100 + originalPrice: 80 + minimumPrice: 90 + channelCode: 'CODE' + product_draft_listing_price_bruce_2: + productDraft: '@product_draft_bruce_2' + price: 150 + originalPrice: 200 + minimumPrice: 90 + channelCode: 'CODE' +Sylius\Component\Core\Model\Taxon: + category_taxon: + code: 'CATEGORY' + currentLocale: 'en_US' + translations: ['@en_us_category_translation'] + children: ['@mug_taxon', '@hat_taxon'] + second_category_taxon: + code: 'SECOND_CATEGORY' + currentLocale: 'en_US' + translations: ['@en_us_second_category_translation'] + children: ['@hat_taxon'] + mug_taxon: + code: 'MUG' + currentLocale: 'en_US' + translations: ['@en_us_mug_taxon_translation'] + parent: '@category_taxon' + position: 0 + hat_taxon: + code: 'HAT' + currentLocale: 'en_US' + translations: ['@en_us_hat_translation'] + parent: '@category_taxon' + position: 1 +Sylius\Component\Taxonomy\Model\TaxonTranslation: + en_us_category_translation: + slug: 'categories' + locale: 'en_US' + name: 'Categories' + description: 'Some description Lorem ipsum dolor sit amet.' + translatable: '@category_taxon' + en_us_second_category_translation: + slug: 'second-categories' + locale: 'en_US' + name: 'Second categories' + description: 'Some description Lorem ipsum dolor sit amet.' + translatable: '@second_category_taxon' + en_us_mug_taxon_translation: + slug: 'categories/mugs' + locale: 'en_US' + name: 'Mugs' + description: 'Some description Lorem ipsum dolor sit amet.' + translatable: '@mug_taxon' + en_us_hat_translation: + slug: 'categories/hats' + locale: 'en_US' + name: 'Hats' + description: 'Some description Lorem ipsum dolor sit amet.' + translatable: '@hat_taxon' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftTaxon: + product_draft_taxon_bruce_1: + productDraft: '@product_draft_bruce_1' + taxon: '@mug_taxon' + position: 1 + product_draft_taxon_bruce_2: + productDraft: '@product_draft_bruce_2' + taxon: '@hat_taxon' + position: 2 diff --git a/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/ProductVariant/InventoryTest/inventory.yml b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/ProductVariant/InventoryTest/inventory.yml new file mode 100644 index 0000000..c6faf49 --- /dev/null +++ b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/ProductVariant/InventoryTest/inventory.yml @@ -0,0 +1,169 @@ +Sylius\Component\Addressing\Model\Country: + country_pl: + code: 'PL' + country_us: + code: 'US' +Sylius\Component\Addressing\Model\Zone: + zone_us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_us: + code: 'US' + belongsTo: '@zone_us' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel: + code: "CODE" + name: "name" + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: "Bruce" + lastName: "Wayne" + email: "bruce.wayne@example.com" + emailCanonical: "bruce.wayne@example.com" + customer_peter: + firstName: "Peter" + lastName: "Weyland" + email: "peter.weyland@example.com" + emailCanonical: "peter.weyland@example.com" + customer_john: + firstName: "John" + lastName: "Smith" + email: "john.smith@example.com" + emailCanonical: "john.smith@example.com" +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: "123password" + roles: ["ROLE_USER", "ROLE_VENDOR"] + enabled: "true" + customer: '@customer_bruce' + username: "bruce.wayne@example.com" + usernameCanonical: "bruce.wayne@example.com" + user_peter: + plainPassword: "123password" + roles: ["ROLE_USER", "ROLE_VENDOR"] + enabled: "true" + customer: '@customer_peter' + username: "peter.weyland@example.com" + usernameCanonical: "peter.weyland@example.com" + user_john: + plainPassword: "123password" + roles: ["ROLE_USER"] + enabled: "true" + customer: '@customer_john' + username: "john.smith@example.com" + usernameCanonical: "john.smith@example.com" +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL31109024026812185484588836' + phoneNumber: '555123123' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL17109024022586255711928552' + phoneNumber: '555444333' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + product_bruce_1: + vendor: '@vendor_bruce' + code: "bruce_1" + enabled: true + channels: ['@channel'] + product_bruce_2: + vendor: '@vendor_bruce' + code: "bruce_2" + enabled: true + channels: ['@channel'] + product_peter_1: + vendor: '@vendor_peter' + code: "peter_2" + enabled: true + channels: [ '@channel' ] +Sylius\Component\Core\Model\ProductVariant: + product_variant_product_bruce_1_1: + product: '@product_bruce_1' + code: "bruce_1_1" + enabled: true + onHold: 2 + onHand: 3 + tracked: true + product_variant_product_bruce_1_2: + product: '@product_bruce_1' + code: "bruce_1_2" + enabled: true + onHand: 1 + tracked: true + product_variant_product_bruce_2_1: + product: '@product_bruce_2' + code: "bruce_2_1" + enabled: true + onHand: 0 + tracked: false + product_variant_product_peter_1_1: + product: '@product_peter_1' + code: "peter_1_1" + enabled: true + onHand: 3 + tracked: true + product_variant_product_peter_1_2: + product: '@product_peter_1' + code: "peter_1_2" + enabled: true + onHand: 1 + tracked: true +Sylius\Component\Core\Model\ChannelPricing: + pricing_product_variant_product_bruce_1_1: + price: 10 + originalPrice: 15 + minimumPrice: 0 + channelCode: 'CODE' + productVariant: '@product_variant_product_bruce_1_1' + pricing_product_variant_product_bruce_1_2: + price: 13 + originalPrice: 25 + minimumPrice: 10 + channelCode: 'CODE' + productVariant: '@product_variant_product_bruce_1_2' + pricing_product_variant_product_bruce_2_1: + price: 8 + originalPrice: 11 + minimumPrice: 5 + channelCode: 'CODE' + productVariant: '@product_variant_product_bruce_2_1' + pricing_product_variant_product_peter_1_1: + price: 9 + originalPrice: 12 + minimumPrice: 5 + channelCode: 'CODE' + productVariant: '@product_variant_product_peter_1_1' + pricing_product_variant_product_peter_1_2: + price: 123 + originalPrice: 222 + minimumPrice: 100 + channelCode: 'CODE' + productVariant: '@product_variant_product_peter_1_2' diff --git a/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/VendorProfileTest/vendor_profile.yml b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/VendorProfileTest/vendor_profile.yml new file mode 100644 index 0000000..827617d --- /dev/null +++ b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/VendorProfileTest/vendor_profile.yml @@ -0,0 +1,121 @@ +Sylius\Component\Addressing\Model\Country: + country_pl: + code: 'PL' + country_us: + code: 'US' +Sylius\Component\Addressing\Model\Zone: + zone_us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_us: + code: 'US' + belongsTo: '@zone_us' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel: + code: "CODE" + name: "name" + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true +Sylius\Component\Core\Model\AdminUser: + test_admin: + enabled: true + username: "Clark Kent" + firstName: "Clark" + lastName: "Kent" + email: "clark.kent@example.com" + emailCanonical: "clark.kent@example.com" + localeCode: 'en_US' + roles: ["ROLE_ADMINISTRATION_ACCESS","ROLE_API_ACCESS"] +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: "Bruce" + lastName: "Wayne" + email: "bruce.wayne@example.com" + emailCanonical: "bruce.wayne@example.com" + customer_peter: + firstName: "Peter" + lastName: "Weyland" + email: "peter.weyland@example.com" + emailCanonical: "peter.weyland@example.com" + customer_john: + firstName: "John" + lastName: "Smith" + email: "john.smith@example.com" + emailCanonical: "john.smith@example.com" +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: "123password" + roles: ["ROLE_USER", "ROLE_VENDOR"] + enabled: "true" + customer: '@customer_bruce' + username: "bruce.wayne@example.com" + usernameCanonical: "bruce.wayne@example.com" + user_peter: + plainPassword: "123password" + roles: ["ROLE_USER", "ROLE_VENDOR"] + enabled: "true" + customer: '@customer_peter' + username: "peter.weyland@example.com" + usernameCanonical: "peter.weyland@example.com" + user_john: + plainPassword: "123password" + roles: ["ROLE_USER"] + enabled: "true" + customer: '@customer_john' + username: "john.smith@example.com" + usernameCanonical: "john.smith@example.com" +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address_bruce: + country: '@country_us' + city: 'Arkham City' + postalCode: '00000' + street: 'Avenue 2115' + vendor_address_peter: + country: '@country_us' + city: 'San Francisco' + postalCode: '94016' + street: 'Unknown 1' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL31109024026812185484588836' + phoneNumber: '555123123' + vendorAddress: '@vendor_address_bruce' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL17109024022586255711928552' + phoneNumber: '555444333' + vendorAddress: '@vendor_address_peter' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Vendor\Entity\LogoImage: + vendor_image_peter: + owner: "@vendor_peter" + path: "/dummy/file/path" +BitBag\OpenMarketplace\Component\Vendor\Entity\BackgroundImage: + vendor_backgroundimage_peter: + owner: "@vendor_peter" + path: "/dummy/file/path" diff --git a/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/VendorRegistrationTest/test_existed_vendor_registration.yml b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/VendorRegistrationTest/test_existed_vendor_registration.yml new file mode 100644 index 0000000..9c72f79 --- /dev/null +++ b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/VendorRegistrationTest/test_existed_vendor_registration.yml @@ -0,0 +1,18 @@ +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + oliver_vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL65109024029994763689555936' + phoneNumber: '333111222' + vendorAddress: '@oliver_vendor_address' + slug: 'oliver-queen-company' + description: 'description' + commission: 10 + commissionType: 'net' diff --git a/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/VendorRegistrationTest/test_vendor_basic_registration.yml b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/VendorRegistrationTest/test_vendor_basic_registration.yml new file mode 100644 index 0000000..96613b9 --- /dev/null +++ b/OpenMarketplace/tests/Functional/DataFixtures/ORM/Api/VendorRegistrationTest/test_vendor_basic_registration.yml @@ -0,0 +1,43 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Addressing\Model\Zone: + pl: + code: 'PL' + name: 'Polska' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_pl: + code: 'PL' + belongsTo: '@pl' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'pl_PL' +Sylius\Component\Core\Model\Channel: + channel: + code: "CODE" + name: "name" + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: "John" + lastName: "Nowak" + email: "test@example.com" + emailCanonical: "test@example.com" +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: "123password" + roles: ["ROLE_USER"] + enabled: "true" + customer: '@customer_oliver' + username: "oliver@queen.com" + usernameCanonical: "oliver@queen.com" diff --git a/OpenMarketplace/tests/Functional/FunctionalTestCase.php b/OpenMarketplace/tests/Functional/FunctionalTestCase.php new file mode 100644 index 0000000..ad4f225 --- /dev/null +++ b/OpenMarketplace/tests/Functional/FunctionalTestCase.php @@ -0,0 +1,57 @@ +dataFixturesPath = __DIR__ . \DIRECTORY_SEPARATOR . 'DataFixtures' . \DIRECTORY_SEPARATOR . 'ORM'; + $this->expectedResponsesPath = __DIR__ . \DIRECTORY_SEPARATOR . 'Responses' . \DIRECTORY_SEPARATOR . 'Expected'; + $this->filesPath = __DIR__ . \DIRECTORY_SEPARATOR . 'Resources' . \DIRECTORY_SEPARATOR . 'files'; + } + + public function getFilePath(string $fileName): string + { + return $this->filesPath . \DIRECTORY_SEPARATOR . $fileName; + } + + protected function getHeaderForLoginShopUser(string $email): array + { + $loginData = $this->logInShopUser($email); + $authorizationHeader = self::getContainer()->getParameter('sylius.api.authorization_header'); + $header['HTTP_' . $authorizationHeader] = 'Bearer ' . $loginData; + + return array_merge($header, self::CONTENT_TYPE_HEADER); + } + + protected function getHeaderForAdmin(string $email): array + { + $loginData = $this->logInAdminUser($email); + $authorizationHeader = self::getContainer()->getParameter('sylius.api.authorization_header'); + $header['HTTP_' . $authorizationHeader] = 'Bearer ' . $loginData; + + return array_merge($header, self::CONTENT_TYPE_HEADER); + } +} diff --git a/OpenMarketplace/tests/Functional/Resources/files/avatar.png b/OpenMarketplace/tests/Functional/Resources/files/avatar.png new file mode 100644 index 0000000..d80a1da Binary files /dev/null and b/OpenMarketplace/tests/Functional/Resources/files/avatar.png differ diff --git a/OpenMarketplace/tests/Functional/Resources/files/product1.png b/OpenMarketplace/tests/Functional/Resources/files/product1.png new file mode 100644 index 0000000..d80a1da Binary files /dev/null and b/OpenMarketplace/tests/Functional/Resources/files/product1.png differ diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/CustomerTest/test_get_shop_customer_by_user.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/CustomerTest/test_get_shop_customer_by_user.json new file mode 100644 index 0000000..9474056 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/CustomerTest/test_get_shop_customer_by_user.json @@ -0,0 +1,18 @@ +{ + "@context": "/api/v2/contexts/Customer", + "@id": "/api/v2/shop/customers/@string@", + "@type": "Customer", + "defaultAddress": "/api/v2/shop/addresses/@string@", + "user": { + "@type": "ShopUser", + "@id": "true", + "vendor": null, + "verified": false + }, + "email": "john.smith@example.com", + "firstName": "John", + "lastName": "Smith", + "gender": "u", + "subscribedToNewsletter": false, + "fullName": "John Smith" +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/CustomerTest/test_get_shop_customer_by_vendor.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/CustomerTest/test_get_shop_customer_by_vendor.json new file mode 100644 index 0000000..5d0f530 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/CustomerTest/test_get_shop_customer_by_vendor.json @@ -0,0 +1,23 @@ +{ + "@context": "/api/v2/contexts/Customer", + "@id": "/api/v2/shop/customers/@string@", + "@type": "Customer", + "defaultAddress": null, + "user": { + "@type": "ShopUser", + "@id": "true", + "vendor": { + "@id": "/api/v2/shop/vendors/@string@", + "@type": "Vendor", + "uuid": "@string@", + "slug": "Wayne-Enterprises-Inc" + }, + "verified": false + }, + "email": "bruce.wayne@example.com", + "firstName": "Bruce", + "lastName": "Wayne", + "gender": "u", + "subscribedToNewsletter": false, + "fullName": "Bruce Wayne" +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/CustomerTest/test_it_get_customer_by_vendor.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/CustomerTest/test_it_get_customer_by_vendor.json new file mode 100644 index 0000000..50760b8 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/CustomerTest/test_it_get_customer_by_vendor.json @@ -0,0 +1,31 @@ +{ + "@context": "/api/v2/contexts/Customer", + "@id": "/api/v2/shop/account/vendor/customers/@string@", + "@type": "Customer", + "defaultAddress": { + "@id": "/api/v2/shop/addresses/@string@", + "@type": "Address", + "firstName": "John", + "lastName": "Smith", + "phoneNumber": null, + "company": null, + "countryCode": "US", + "provinceCode": null, + "provinceName": null, + "street": "Avenue 2115", + "city": "Arkham City", + "postcode": "00000" + }, + "user": { + "@type": "ShopUser", + "@id": "true", + "enabled": true, + "vendor": null, + "verified": false + }, + "email": "john.smith@example.com", + "firstName": "John", + "lastName": "Smith", + "gender": "u", + "phoneNumber": "123456789" +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/CustomerTest/test_it_get_customers_by_vendor.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/CustomerTest/test_it_get_customers_by_vendor.json new file mode 100644 index 0000000..0b01630 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/CustomerTest/test_it_get_customers_by_vendor.json @@ -0,0 +1,86 @@ +{ + "@context": "/api/v2/contexts/Customer", + "@id": "/api/v2/shop/account/vendor/customers", + "@type": "hydra:Collection", + "hydra:member": [ + { + "@id": "/api/v2/shop/account/vendor/customers/@string@", + "@type": "Customer", + "defaultAddress": null, + "user": { + "@type": "ShopUser", + "@id": "true", + "enabled": true, + "vendor": "/api/v2/shop/vendors/@string@", + "verified": false + }, + "email": "peter.weyland@example.com", + "firstName": "Peter", + "lastName": "Weyland", + "gender": "u", + "phoneNumber": null + }, + { + "@id": "/api/v2/shop/account/vendor/customers/@string@", + "@type": "Customer", + "defaultAddress": { + "@id": "/api/v2/shop/addresses/@string@", + "@type": "Address", + "firstName": "John", + "lastName": "Smith", + "phoneNumber": null, + "company": null, + "countryCode": "US", + "provinceCode": null, + "provinceName": null, + "street": "Avenue 2115", + "city": "Arkham City", + "postcode": "00000" + }, + "user": { + "@type": "ShopUser", + "@id": "true", + "enabled": true, + "vendor": null, + "verified": false + }, + "email": "john.smith@example.com", + "firstName": "John", + "lastName": "Smith", + "gender": "u", + "phoneNumber": "123456789" + } + ], + "hydra:totalItems": 2, + "hydra:search": { + "@type": "hydra:IriTemplate", + "hydra:template": "/api/v2/shop/account/vendor/customers{?firstName,lastName,email,user.enabled}", + "hydra:variableRepresentation": "BasicRepresentation", + "hydra:mapping": [ + { + "@type": "IriTemplateMapping", + "variable": "firstName", + "property": "firstName", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "lastName", + "property": "lastName", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "email", + "property": "email", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "user.enabled", + "property": "user.enabled", + "required": false + } + ] + } +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/CustomerTest/test_it_get_customers_by_vendor_filter_email.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/CustomerTest/test_it_get_customers_by_vendor_filter_email.json new file mode 100644 index 0000000..551fbce --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/CustomerTest/test_it_get_customers_by_vendor_filter_email.json @@ -0,0 +1,73 @@ +{ + "@context": "/api/v2/contexts/Customer", + "@id": "/api/v2/shop/account/vendor/customers", + "@type": "hydra:Collection", + "hydra:member": [ + { + "@id": "/api/v2/shop/account/vendor/customers/@string@", + "@type": "Customer", + "defaultAddress": { + "@id": "/api/v2/shop/addresses/@string@", + "@type": "Address", + "firstName": "John", + "lastName": "Smith", + "phoneNumber": null, + "company": null, + "countryCode": "US", + "provinceCode": null, + "provinceName": null, + "street": "Avenue 2115", + "city": "Arkham City", + "postcode": "00000" + }, + "user": { + "@type": "ShopUser", + "@id": "true", + "enabled": true, + "vendor": null, + "verified": false + }, + "email": "john.smith@example.com", + "firstName": "John", + "lastName": "Smith", + "gender": "u", + "phoneNumber": "123456789" + } + ], + "hydra:totalItems": 1, + "hydra:view": { + "@id": "/api/v2/shop/account/vendor/customers?email=john", + "@type": "hydra:PartialCollectionView" + }, + "hydra:search": { + "@type": "hydra:IriTemplate", + "hydra:template": "/api/v2/shop/account/vendor/customers{?firstName,lastName,email,user.enabled}", + "hydra:variableRepresentation": "BasicRepresentation", + "hydra:mapping": [ + { + "@type": "IriTemplateMapping", + "variable": "firstName", + "property": "firstName", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "lastName", + "property": "lastName", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "email", + "property": "email", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "user.enabled", + "property": "user.enabled", + "required": false + } + ] + } +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_creating_attribute_by_vendor_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_creating_attribute_by_vendor_response.json new file mode 100644 index 0000000..b69c584 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_creating_attribute_by_vendor_response.json @@ -0,0 +1,21 @@ +{ + "@context": "\/api\/v2\/contexts\/DraftAttribute", + "@id": "\/api\/v2\/shop\/account\/vendor\/product-draft/attributes\/@string@", + "@type": "DraftAttribute", + "vendor": "\/api\/v2\/shop\/vendors\/@string@", + "uuid": "@string@", + "code": "test", + "type": "text", + "configuration": [], + "storageType": "text", + "position": 1, + "translations": { + "en_US": { + "@id": "/api/v2/shop/account/vendor/product-draft/attribute-translations/@string@", + "@type": "DraftAttributeTranslation", + "uuid": "@string@", + "name": "test", + "locale": "en_US" + } + } +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_it_get_attribute_by_owner_vendor_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_it_get_attribute_by_owner_vendor_response.json new file mode 100644 index 0000000..c45008e --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_it_get_attribute_by_owner_vendor_response.json @@ -0,0 +1,21 @@ +{ + "@context": "\/api\/v2\/contexts\/DraftAttribute", + "@id": "\/api\/v2\/shop\/account\/vendor\/product-draft\/attributes\/@string@", + "@type": "DraftAttribute", + "vendor": "\/api\/v2\/shop\/vendors\/@string@", + "uuid": "@string@", + "code": "attribute_bruce_1", + "type": "text", + "configuration": [], + "storageType": "text", + "position": 0, + "translations": { + "en_US": { + "@id": "/api/v2/shop/account/vendor/product-draft/attribute-translations/@string@", + "@type": "DraftAttributeTranslation", + "uuid": "@string@", + "name": "attribute_bruce_1_us", + "locale": "en_US" + } + } +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_it_get_only_draft_attributes_for_current_vendor_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_it_get_only_draft_attributes_for_current_vendor_response.json new file mode 100644 index 0000000..8e1027d --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_it_get_only_draft_attributes_for_current_vendor_response.json @@ -0,0 +1,28 @@ +{ + "@context": "\/api\/v2\/contexts\/DraftAttribute", + "@id": "\/api\/v2\/shop\/account\/vendor\/product-draft\/attributes", + "@type": "hydra:Collection", + "hydra:member": [ + { + "@id": "\/api\/v2\/shop\/account\/vendor\/product-draft\/attributes\/@string@", + "@type": "DraftAttribute", + "vendor": "\/api\/v2\/shop\/vendors\/@string@", + "uuid": "@string@", + "code": "attribute_bruce_1", + "type": "text", + "configuration": [], + "storageType": "text", + "position": "@integer@", + "translations": { + "en_US": { + "@id": "/api/v2/shop/account/vendor/product-draft/attribute-translations/@string@", + "@type": "DraftAttributeTranslation", + "uuid": "@string@", + "name": "attribute_bruce_1_us", + "locale": "en_US" + } + } + } + ], + "hydra:totalItems": 1 +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_it_update_attribute_by_vendor_owner_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_it_update_attribute_by_vendor_owner_response.json new file mode 100644 index 0000000..6d2fa11 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_it_update_attribute_by_vendor_owner_response.json @@ -0,0 +1,23 @@ +{ + "@context": "\/api\/v2\/contexts\/DraftAttribute", + "@id": "\/api\/v2\/shop\/account\/vendor\/product-draft\/attributes\/@string@", + "@type": "DraftAttribute", + "vendor": "\/api\/v2\/shop\/vendors\/@string@", + "uuid": "@string@", + "code": "attribute_bruce_1", + "type": "text", + "configuration": { + "min": 2 + }, + "storageType": "text", + "position": 0, + "translations": { + "en_US": { + "@id": "/api/v2/shop/account/vendor/product-draft/attribute-translations/@string@", + "@type": "DraftAttributeTranslation", + "uuid": "@string@", + "name": "attribute_bruce_1_us", + "locale": "en_US" + } + } +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_it_update_attribute_translation_by_vendor_owner_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_it_update_attribute_translation_by_vendor_owner_response.json new file mode 100644 index 0000000..0bd8e23 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_it_update_attribute_translation_by_vendor_owner_response.json @@ -0,0 +1,8 @@ +{ + "@context": "\/api\/v2\/contexts\/DraftAttributeTranslation", + "@id": "\/api\/v2\/shop\/account\/vendor\/product-draft/attribute-translations\/@string@", + "@type": "DraftAttributeTranslation", + "uuid": "@string@", + "name": "changed translation name", + "locale": "en_US" +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_validate_not_blank_rules_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_validate_not_blank_rules_response.json new file mode 100644 index 0000000..15ef837 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/DraftAttributeTest/test_validate_not_blank_rules_response.json @@ -0,0 +1,33 @@ +{ + "@context": "\/api\/v2\/contexts\/ConstraintViolationList", + "@type": "ConstraintViolationList", + "hydra:title": "An error occurred", + "hydra:description": "code: This field cannot be empty\ntype: This field cannot be empty\nstorageType: This field cannot be empty\ntranslations[].locale: This field cannot be empty\ntranslations[].name: This field cannot be empty", + "violations": [ + { + "propertyPath": "code", + "message": "This field cannot be empty", + "code": "c1051bb4-d103-4f74-8988-acbcafc7fdc3" + }, + { + "propertyPath": "type", + "message": "This field cannot be empty", + "code": "c1051bb4-d103-4f74-8988-acbcafc7fdc3" + }, + { + "propertyPath": "storageType", + "message": "This field cannot be empty", + "code": "c1051bb4-d103-4f74-8988-acbcafc7fdc3" + }, + { + "propertyPath": "translations[].locale", + "message": "This field cannot be empty", + "code": "c1051bb4-d103-4f74-8988-acbcafc7fdc3" + }, + { + "propertyPath": "translations[].name", + "message": "This field cannot be empty", + "code": "c1051bb4-d103-4f74-8988-acbcafc7fdc3" + } + ] +} \ No newline at end of file diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_get_shop_orders_by_shop_user.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_get_shop_orders_by_shop_user.json new file mode 100644 index 0000000..4a999c5 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_get_shop_orders_by_shop_user.json @@ -0,0 +1,29 @@ +{ + "@context": "/api/v2/contexts/Order", + "@id": "/api/v2/shop/orders", + "@type": "hydra:Collection", + "hydra:member": [ + { + "@id": "/api/v2/shop/orders/bruce_order_made_by_john_1", + "@type": "Order", + "tokenValue": "bruce_order_made_by_john_1", + "id": "@integer@", + "itemsTotal": 0 + }, + { + "@id": "/api/v2/shop/orders/bruce_order_made_by_john_2", + "@type": "Order", + "tokenValue": "bruce_order_made_by_john_2", + "id": "@integer@", + "itemsTotal": 0 + }, + { + "@id": "/api/v2/shop/orders/peter_order_made_by_john", + "@type": "Order", + "tokenValue": "peter_order_made_by_john", + "id": "@integer@", + "itemsTotal": 0 + } + ], + "hydra:totalItems": 3 +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_get_shop_orders_by_vendor.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_get_shop_orders_by_vendor.json new file mode 100644 index 0000000..c00a23c --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_get_shop_orders_by_vendor.json @@ -0,0 +1,22 @@ +{ + "@context": "/api/v2/contexts/Order", + "@id": "/api/v2/shop/orders", + "@type": "hydra:Collection", + "hydra:member": [ + { + "@id": "/api/v2/shop/orders/order_made_by_peter_1", + "@type": "Order", + "tokenValue": "order_made_by_peter_1", + "id": "@integer@", + "itemsTotal": 0 + }, + { + "@id": "/api/v2/shop/orders/order_made_by_peter_2", + "@type": "Order", + "tokenValue": "order_made_by_peter_2", + "id": "@integer@", + "itemsTotal": 0 + } + ], + "hydra:totalItems": 2 +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_it_cancel_order_by_vendor.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_it_cancel_order_by_vendor.json new file mode 100644 index 0000000..aa39cca --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_it_cancel_order_by_vendor.json @@ -0,0 +1,47 @@ +{ + "@context": "/api/v2/contexts/Order", + "@id": "/api/v2/shop/account/vendor/orders/bruce_order_made_by_john_2", + "@type": "Order", + "customer": "/api/v2/shop/account/vendor/customers/@string@", + "payments": [], + "shipments": [ + { + "@id": "/api/v2/shop/shipments/@string@", + "@type": "Shipment", + "id": "@integer@", + "method": "/api/v2/shop/shipping-methods/fedex", + "vendor": { + "@id": "/api/v2/shop/@string@", + "@type": "Vendor", + "uuid": "@string@", + "slug": "Wayne-Enterprises-Inc" + } + } + ], + "currencyCode": "USD", + "localeCode": "en-US", + "checkoutState": "completed", + "paymentState": "paid", + "shippingState": "cart", + "tokenValue": "bruce_order_made_by_john_2", + "id": "@integer@", + "items": [ + { + "@id": "/api/v2/shop/order-items/@string@", + "@type": "OrderItem", + "variant": "/api/v2/shop/product-variants/bruce_1_2", + "id": "@integer@", + "quantity": 0, + "unitPrice": 0, + "originalUnitPrice": 0, + "total": 0, + "subtotal": 0 + } + ], + "itemsTotal": 0, + "total": 0, + "state": "cancelled", + "taxTotal": 0, + "shippingTotal": 0, + "orderPromotionTotal": 0 +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_it_get_order_by_vendor.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_it_get_order_by_vendor.json new file mode 100644 index 0000000..a91678e --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_it_get_order_by_vendor.json @@ -0,0 +1,87 @@ +{ + "@context": "/api/v2/contexts/Order", + "@id": "/api/v2/shop/account/vendor/orders/bruce_order_made_by_john_1", + "@type": "Order", + "customer": "/api/v2/shop/account/vendor/customers/@string@", + "shippingAddress": { + "@id": "/api/v2/shop/addresses/@string@", + "@type": "Address", + "id": "@integer@", + "firstName": "John", + "lastName": "Smith", + "countryCode": "US", + "street": "Avenue 2115", + "city": "Arkham City", + "postcode": "00000" + }, + "billingAddress": { + "@id": "/api/v2/shop/addresses/@string@", + "@type": "Address", + "id": "@integer@", + "firstName": "John", + "lastName": "Smith", + "countryCode": "US", + "street": "Avenue 2115", + "city": "Arkham City", + "postcode": "00000" + }, + "shipments": [ + "/api/v2/shop/shipments/@string@" + ], + "currencyCode": "USD", + "localeCode": "en-US", + "checkoutState": "completed", + "paymentState": "awaiting_payment", + "tokenValue": "bruce_order_made_by_john_1", + "id": "@integer@", + "items": [ + { + "@id": "/api/v2/shop/order-items/@string@", + "@type": "OrderItem", + "variant": { + "@id": "/api/v2/shop/product-variants/bruce_1_1", + "@type": "ProductVariant", + "code": "bruce_1_1" + }, + "id": "@integer@", + "order": "/api/v2/shop/account/vendor/orders/bruce_order_made_by_john_1", + "quantity": 1, + "unitPrice": 0, + "originalUnitPrice": 0, + "total": 0, + "units": [ + { + "@id": "/api/v2/shop/order-item-units/@string@", + "@type": "OrderItemUnit", + "id": "@integer@", + "adjustments": [], + "adjustmentsTotal": 0, + "shippable": { + "@id": "/api/v2/shop/product-variants/bruce_1_1", + "@type": "ProductVariant", + "code": "bruce_1_1" + } + } + ], + "adjustments": [], + "adjustmentsTotal": 0, + "product": { + "@id": "/api/v2/shop/products/bruce_1", + "@type": "Product", + "defaultVariant": "/api/v2/shop/product-variants/bruce_1_1" + }, + "discountedUnitPrice": 0, + "subtotal": 0, + "adjustmentsRecursively": [], + "adjustmentsTotalRecursively": 0 + } + ], + "itemsTotal": 0, + "adjustments": [], + "adjustmentsTotal": 0, + "total": 0, + "state": "new", + "taxTotal": 0, + "shippingTotal": 0, + "orderPromotionTotal": 0 +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_it_get_orders_by_vendor.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_it_get_orders_by_vendor.json new file mode 100644 index 0000000..60001e2 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_it_get_orders_by_vendor.json @@ -0,0 +1,157 @@ +{ + "@context": "/api/v2/contexts/Order", + "@id": "/api/v2/shop/account/vendor/orders", + "@type": "hydra:Collection", + "hydra:member": [ + { + "@id": "/api/v2/shop/account/vendor/orders/bruce_order_made_by_john_1", + "@type": "Order", + "customer": { + "@id": "/api/v2/shop/account/vendor/customers/@string@", + "@type": "Customer", + "email": "john.smith@example.com", + "firstName": "John", + "lastName": "Smith", + "phoneNumber": "123456789", + "subscribedToNewsletter": false + }, + "shipments": [ + { + "@id": "/api/v2/shop/shipments/@string@", + "@type": "Shipment", + "method": { + "@id": "/api/v2/shop/shipping-methods/ups", + "@type": "ShippingMethod", + "code": "ups" + } + } + ], + "currencyCode": "USD", + "checkoutState": "completed", + "paymentState": "awaiting_payment", + "id": "@integer@", + "state": "new" + }, + { + "@id": "/api/v2/shop/account/vendor/orders/bruce_order_made_by_john_2", + "@type": "Order", + "customer": { + "@id": "/api/v2/shop/account/vendor/customers/@string@", + "@type": "Customer", + "email": "john.smith@example.com", + "firstName": "John", + "lastName": "Smith", + "phoneNumber": "123456789", + "subscribedToNewsletter": false + }, + "shipments": [ + { + "@id": "/api/v2/shop/shipments/@string@", + "@type": "Shipment", + "method": { + "@id": "/api/v2/shop/shipping-methods/fedex", + "@type": "ShippingMethod", + "code": "fedex" + } + } + ], + "currencyCode": "USD", + "checkoutState": "completed", + "paymentState": "paid", + "id": "@integer@", + "state": "new" + } + ], + "hydra:totalItems": 2, + "hydra:search": { + "@type": "hydra:IriTemplate", + "hydra:template": "/api/v2/shop/account/vendor/orders{?number,state,state[],paymentState,paymentState[],shippingState,shippingState[],shipments.method.code,shipments.method.code[],customer.email,checkoutCompletedAt[before],checkoutCompletedAt[strictly_before],checkoutCompletedAt[after],checkoutCompletedAt[strictly_after]}", + "hydra:variableRepresentation": "BasicRepresentation", + "hydra:mapping": [ + { + "@type": "IriTemplateMapping", + "variable": "number", + "property": "number", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "state", + "property": "state", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "state[]", + "property": "state", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "paymentState", + "property": "paymentState", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "paymentState[]", + "property": "paymentState", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "shippingState", + "property": "shippingState", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "shippingState[]", + "property": "shippingState", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "shipments.method.code", + "property": "shipments.method.code", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "shipments.method.code[]", + "property": "shipments.method.code", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "customer.email", + "property": "customer.email", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "checkoutCompletedAt[before]", + "property": "checkoutCompletedAt", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "checkoutCompletedAt[strictly_before]", + "property": "checkoutCompletedAt", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "checkoutCompletedAt[after]", + "property": "checkoutCompletedAt", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "checkoutCompletedAt[strictly_after]", + "property": "checkoutCompletedAt", + "required": false + } + ] + } +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_it_get_orders_by_vendor_filter_payment_state.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_it_get_orders_by_vendor_filter_payment_state.json new file mode 100644 index 0000000..187a623 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/OrderTest/test_it_get_orders_by_vendor_filter_payment_state.json @@ -0,0 +1,132 @@ +{ + "@context": "/api/v2/contexts/Order", + "@id": "/api/v2/shop/account/vendor/orders", + "@type": "hydra:Collection", + "hydra:member": [ + { + "@id": "/api/v2/shop/account/vendor/orders/bruce_order_made_by_john_2", + "@type": "Order", + "customer": { + "@id": "/api/v2/shop/account/vendor/customers/@string@", + "@type": "Customer", + "email": "john.smith@example.com", + "firstName": "John", + "lastName": "Smith", + "phoneNumber": "123456789", + "subscribedToNewsletter": false + }, + "shipments": [ + { + "@id": "/api/v2/shop/shipments/@string@", + "@type": "Shipment", + "method": { + "@id": "/api/v2/shop/shipping-methods/fedex", + "@type": "ShippingMethod", + "code": "fedex" + } + } + ], + "currencyCode": "USD", + "checkoutState": "completed", + "paymentState": "paid", + "id": "@integer@", + "state": "new" + } + ], + "hydra:totalItems": 1, + "hydra:view": { + "@id": "/api/v2/shop/account/vendor/orders?paymentState=paid", + "@type": "hydra:PartialCollectionView" + }, + "hydra:search": { + "@type": "hydra:IriTemplate", + "hydra:template": "/api/v2/shop/account/vendor/orders{?number,state,state[],paymentState,paymentState[],shippingState,shippingState[],shipments.method.code,shipments.method.code[],customer.email,checkoutCompletedAt[before],checkoutCompletedAt[strictly_before],checkoutCompletedAt[after],checkoutCompletedAt[strictly_after]}", + "hydra:variableRepresentation": "BasicRepresentation", + "hydra:mapping": [ + { + "@type": "IriTemplateMapping", + "variable": "number", + "property": "number", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "state", + "property": "state", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "state[]", + "property": "state", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "paymentState", + "property": "paymentState", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "paymentState[]", + "property": "paymentState", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "shippingState", + "property": "shippingState", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "shippingState[]", + "property": "shippingState", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "shipments.method.code", + "property": "shipments.method.code", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "shipments.method.code[]", + "property": "shipments.method.code", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "customer.email", + "property": "customer.email", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "checkoutCompletedAt[before]", + "property": "checkoutCompletedAt", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "checkoutCompletedAt[strictly_before]", + "property": "checkoutCompletedAt", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "checkoutCompletedAt[after]", + "property": "checkoutCompletedAt", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "checkoutCompletedAt[strictly_after]", + "property": "checkoutCompletedAt", + "required": false + } + ] + } +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductDraftTest/test_it_get_by_current_vendor.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductDraftTest/test_it_get_by_current_vendor.json new file mode 100644 index 0000000..d78eb21 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductDraftTest/test_it_get_by_current_vendor.json @@ -0,0 +1,26 @@ +{ + "@context": "/api/v2/contexts/Draft", + "@id": "/api/v2/shop/account/vendor/product-drafts/@string@", + "@type": "Draft", + "uuid": "@string@", + "code": "product_draft_bruce_1", + "status": "created", + "verifiedAt": null, + "publishedAt": null, + "images": [ + [] + ], + "translations": { + "en_US": "/api/v2/shop/account/vendor/product-draft/translations/@string@" + }, + "productListingPrices": { + "CODE": [] + }, + "attributes": [ + [] + ], + "mainTaxon": "/api/v2/shop/taxons/CATEGORY", + "productDraftTaxons": [ + [] + ] +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_creating_product_listing_by_vendor_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_creating_product_listing_by_vendor_response.json new file mode 100644 index 0000000..e436d48 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_creating_product_listing_by_vendor_response.json @@ -0,0 +1,65 @@ +{ + "@context": "\/api\/v2\/contexts\/Listing", + "@id": "\/api\/v2\/shop\/account\/vendor\/product-listings\/@string@", + "@type": "Listing", + "uuid": "@string@", + "code": "test", + "enabled": true, + "verificationStatus": "created", + "latestDraft": { + "@id": "\/api\/v2\/shop\/account\/vendor\/product-drafts\/@string@", + "@type": "Draft", + "uuid": "@string@", + "code": "test", + "status": "created", + "images": [ + { + "@type": "DraftImage", + "uuid": "@string@", + "path": "@string@\/product1.png" + } + ], + "translations": [ + { + "@id": "\/api\/v2\/shop\/account\/vendor\/product-draft\/translations\/@string@", + "@type": "DraftTranslation", + "uuid": "@string@", + "name": "Test", + "description": "Test description", + "metaKeywords": "Test metaKeywords", + "metaDescription": "Test metaDescription", + "shortDescription": "Test shortDescription", + "locale": "en_US" + } + ], + "productListingPrices": [ + { + "@type": "ListingPrice", + "uuid": "@string@", + "price": 100, + "originalPrice": 110, + "minimumPrice": 80, + "channelCode": "CODE" + } + ], + "attributes": [ + { + "@type": "DraftAttributeValue", + "uuid": "@string@", + "attribute": "\/api\/v2\/shop\/account\/vendor\/product-draft\/attributes\/@string@", + "value": "example text value" + } + ], + "mainTaxon": "\/api\/v2\/shop\/taxons\/CATEGORY", + "productDraftTaxons": [ + { + "@type": "DraftTaxon", + "uuid": "@string@", + "taxon": "\/api\/v2\/shop\/taxons\/MUG", + "position": 2 + } + ] + }, + "product": null, + "lastVerifiedAt": null +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_gets_only_product_listings_for_current_vendor_filter_by_code.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_gets_only_product_listings_for_current_vendor_filter_by_code.json new file mode 100644 index 0000000..fc12246 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_gets_only_product_listings_for_current_vendor_filter_by_code.json @@ -0,0 +1,98 @@ +{ + "@context": "\/api\/v2\/contexts\/Listing", + "@id": "\/api\/v2\/shop\/account\/vendor\/product-listings", + "@type": "hydra:Collection", + "hydra:member": [ + { + "@id": "\/api\/v2\/shop\/account\/vendor\/product-listings\/@string@", + "@type": "Listing", + "uuid": "@string@", + "code": "product_listing_bruce_1", + "enabled": true, + "verificationStatus": "created", + "latestDraft": { + "@id": "\/api\/v2\/shop\/account\/vendor\/product-drafts\/@string@", + "@type": "Draft", + "uuid": "@string@", + "code": "product_draft_bruce_1", + "status": "created", + "verifiedAt": null, + "publishedAt": null, + "images": [], + "translations": { + "en_US": { + "@id": "\/api\/v2\/shop\/account\/vendor\/product-draft\/translations\/@string@", + "@type": "DraftTranslation", + "uuid": "@string@", + "name": "product_draft_bruce_1_translations_us", + "slug": "product_draft_bruce_1_translations_us", + "description": null, + "metaKeywords": null, + "metaDescription": null, + "shortDescription": null, + "locale": "en_US" + } + }, + "productListingPrices": { + "CODE": { + "@type": "ListingPrice", + "uuid": "@string@", + "price": 100, + "originalPrice": 80, + "minimumPrice": 90, + "channelCode": "CODE" + } + }, + "attributes": [ + { + "@type": "DraftAttributeValue", + "uuid": "@string@", + "attribute": "\/api\/v2\/shop\/account\/vendor\/product-draft\/attributes\/@string@", + "value": "example value" + } + ], + "mainTaxon": "\/api\/v2\/shop\/taxons\/CATEGORY", + "productDraftTaxons": [ + { + "@type": "DraftTaxon", + "uuid": "@string@", + "taxon": "\/api\/v2\/shop\/taxons\/MUG", + "position": 1 + } + ] + }, + "product": null, + "lastVerifiedAt": null + } + ], + "hydra:totalItems": 1, + "hydra:view": { + "@id": "/api/v2/shop/account/vendor/product-listings?code=bruce_1", + "@type": "hydra:PartialCollectionView" + }, + "hydra:search": { + "@type": "hydra:IriTemplate", + "hydra:template": "/api/v2/shop/account/vendor/product-listings{?code,verificationStatus,verificationStatus[]}", + "hydra:variableRepresentation": "BasicRepresentation", + "hydra:mapping": [ + { + "@type": "IriTemplateMapping", + "variable": "code", + "property": "code", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "verificationStatus", + "property": "verificationStatus", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "verificationStatus[]", + "property": "verificationStatus", + "required": false + } + ] + } +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_gets_only_product_listings_for_current_vendor_filter_by_verification_status.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_gets_only_product_listings_for_current_vendor_filter_by_verification_status.json new file mode 100644 index 0000000..f066a1a --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_gets_only_product_listings_for_current_vendor_filter_by_verification_status.json @@ -0,0 +1,98 @@ +{ + "@context": "\/api\/v2\/contexts\/Listing", + "@id": "\/api\/v2\/shop\/account\/vendor\/product-listings", + "@type": "hydra:Collection", + "hydra:member": [ + { + "@id": "\/api\/v2\/shop\/account\/vendor\/product-listings\/@string@", + "@type": "Listing", + "uuid": "@string@", + "code": "product_listing_bruce_2", + "enabled": true, + "verificationStatus": "verified", + "latestDraft": { + "@id": "\/api\/v2\/shop\/account\/vendor\/product-drafts\/@string@", + "@type": "Draft", + "uuid": "@string@", + "code": "product_draft_bruce_2", + "status": "created", + "verifiedAt": null, + "publishedAt": null, + "images": [], + "translations": { + "en_US": { + "@id": "\/api\/v2\/shop\/account\/vendor\/product-draft\/translations\/@string@", + "@type": "DraftTranslation", + "uuid": "@string@", + "name": "product_draft_bruce_2_translations_us", + "slug": "product_draft_bruce_2_translations_us", + "description": null, + "metaKeywords": null, + "metaDescription": null, + "shortDescription": null, + "locale": "en_US" + } + }, + "productListingPrices": { + "CODE": { + "@type": "ListingPrice", + "uuid": "@string@", + "price": 150, + "originalPrice": 200, + "minimumPrice": 90, + "channelCode": "CODE" + } + }, + "attributes": [ + { + "@type": "DraftAttributeValue", + "uuid": "@string@", + "attribute": "\/api\/v2\/shop\/account\/vendor\/product-draft\/attributes\/@string@", + "value": "example value" + } + ], + "mainTaxon": "\/api\/v2\/shop\/taxons\/CATEGORY", + "productDraftTaxons": [ + { + "@type": "DraftTaxon", + "uuid": "@string@", + "taxon": "\/api\/v2\/shop\/taxons\/HAT", + "position": 2 + } + ] + }, + "product": null, + "lastVerifiedAt": null + } + ], + "hydra:totalItems": 1, + "hydra:view": { + "@id": "/api/v2/shop/account/vendor/product-listings?verificationStatus=verified", + "@type": "hydra:PartialCollectionView" + }, + "hydra:search": { + "@type": "hydra:IriTemplate", + "hydra:template": "/api/v2/shop/account/vendor/product-listings{?code,verificationStatus,verificationStatus[]}", + "hydra:variableRepresentation": "BasicRepresentation", + "hydra:mapping": [ + { + "@type": "IriTemplateMapping", + "variable": "code", + "property": "code", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "verificationStatus", + "property": "verificationStatus", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "verificationStatus[]", + "property": "verificationStatus", + "required": false + } + ] + } +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_gets_only_product_listings_for_current_vendor_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_gets_only_product_listings_for_current_vendor_response.json new file mode 100644 index 0000000..6df7955 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_gets_only_product_listings_for_current_vendor_response.json @@ -0,0 +1,155 @@ +{ + "@context": "\/api\/v2\/contexts\/Listing", + "@id": "\/api\/v2\/shop\/account\/vendor\/product-listings", + "@type": "hydra:Collection", + "hydra:member": [ + { + "@id": "\/api\/v2\/shop\/account\/vendor\/product-listings\/@string@", + "@type": "Listing", + "uuid": "@string@", + "code": "product_listing_bruce_1", + "enabled": true, + "verificationStatus": "created", + "latestDraft": { + "@id": "\/api\/v2\/shop\/account\/vendor\/product-drafts\/@string@", + "@type": "Draft", + "uuid": "@string@", + "code": "product_draft_bruce_1", + "status": "created", + "verifiedAt": null, + "publishedAt": null, + "images": [], + "translations": { + "en_US": { + "@id": "\/api\/v2\/shop\/account\/vendor\/product-draft\/translations\/@string@", + "@type": "DraftTranslation", + "uuid": "@string@", + "name": "product_draft_bruce_1_translations_us", + "slug": "product_draft_bruce_1_translations_us", + "description": null, + "metaKeywords": null, + "metaDescription": null, + "shortDescription": null, + "locale": "en_US" + } + }, + "productListingPrices": { + "CODE": { + "@type": "ListingPrice", + "uuid": "@string@", + "price": 100, + "originalPrice": 80, + "minimumPrice": 90, + "channelCode": "CODE" + } + }, + "attributes": [ + { + "@type": "DraftAttributeValue", + "uuid": "@string@", + "attribute": "\/api\/v2\/shop\/account\/vendor\/product-draft\/attributes\/@string@", + "value": "example value" + } + ], + "mainTaxon": "\/api\/v2\/shop\/taxons\/CATEGORY", + "productDraftTaxons": [ + { + "@type": "DraftTaxon", + "uuid": "@string@", + "taxon": "\/api\/v2\/shop\/taxons\/MUG", + "position": 1 + } + ] + }, + "product": null, + "lastVerifiedAt": null + }, + { + "@id": "\/api\/v2\/shop\/account\/vendor\/product-listings\/@string@", + "@type": "Listing", + "uuid": "@string@", + "code": "product_listing_bruce_2", + "enabled": true, + "verificationStatus": "verified", + "latestDraft": { + "@id": "\/api\/v2\/shop\/account\/vendor\/product-drafts\/@string@", + "@type": "Draft", + "uuid": "@string@", + "code": "product_draft_bruce_2", + "status": "created", + "verifiedAt": null, + "publishedAt": null, + "images": [], + "translations": { + "en_US": { + "@id": "\/api\/v2\/shop\/account\/vendor\/product-draft\/translations\/@string@", + "@type": "DraftTranslation", + "uuid": "@string@", + "name": "product_draft_bruce_2_translations_us", + "slug": "product_draft_bruce_2_translations_us", + "description": null, + "metaKeywords": null, + "metaDescription": null, + "shortDescription": null, + "locale": "en_US" + } + }, + "productListingPrices": { + "CODE": { + "@type": "ListingPrice", + "uuid": "@string@", + "price": 150, + "originalPrice": 200, + "minimumPrice": 90, + "channelCode": "CODE" + } + }, + "attributes": [ + { + "@type": "DraftAttributeValue", + "uuid": "@string@", + "attribute": "\/api\/v2\/shop\/account\/vendor\/product-draft\/attributes\/@string@", + "value": "example value" + } + ], + "mainTaxon": "\/api\/v2\/shop\/taxons\/CATEGORY", + "productDraftTaxons": [ + { + "@type": "DraftTaxon", + "uuid": "@string@", + "taxon": "\/api\/v2\/shop\/taxons\/HAT", + "position": 2 + } + ] + }, + "product": null, + "lastVerifiedAt": null + } + ], + "hydra:totalItems": 2, + "hydra:search": { + "@type": "hydra:IriTemplate", + "hydra:template": "/api/v2/shop/account/vendor/product-listings{?code,verificationStatus,verificationStatus[]}", + "hydra:variableRepresentation": "BasicRepresentation", + "hydra:mapping": [ + { + "@type": "IriTemplateMapping", + "variable": "code", + "property": "code", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "verificationStatus", + "property": "verificationStatus", + "required": false + }, + { + "@type": "IriTemplateMapping", + "variable": "verificationStatus[]", + "property": "verificationStatus", + "required": false + } + ] + } +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_gets_product_listing_by_owner_vendor_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_gets_product_listing_by_owner_vendor_response.json new file mode 100644 index 0000000..21358b9 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_gets_product_listing_by_owner_vendor_response.json @@ -0,0 +1,62 @@ +{ + "@context": "\/api\/v2\/contexts\/Listing", + "@id": "\/api\/v2\/shop\/account\/vendor\/product-listings\/@string@", + "@type": "Listing", + "uuid": "@string@", + "code": "product_listing_bruce_1", + "enabled": true, + "verificationStatus": "created", + "latestDraft": { + "@id": "\/api\/v2\/shop\/account\/vendor\/product-drafts\/@string@", + "@type": "Draft", + "uuid": "@string@", + "code": "product_draft_bruce_1", + "status": "created", + "verifiedAt": null, + "publishedAt": null, + "images": [], + "translations": { + "en_US": { + "@id": "\/api\/v2\/shop\/account\/vendor\/product-draft/translations\/@string@", + "@type": "DraftTranslation", + "uuid": "@string@", + "name": "product_draft_bruce_1_translations_us", + "slug": "product_draft_bruce_1_translations_us", + "description": null, + "metaKeywords": null, + "metaDescription": null, + "shortDescription": null, + "locale": "en_US" + } + }, + "productListingPrices": { + "CODE": { + "@type": "ListingPrice", + "uuid": "@string@", + "price": 100, + "originalPrice": 80, + "minimumPrice": 90, + "channelCode": "CODE" + } + }, + "attributes": [ + { + "@type": "DraftAttributeValue", + "uuid": "@string@", + "attribute": "\/api\/v2\/shop\/account\/vendor\/product-draft\/attributes\/@string@", + "value": "example value" + } + ], + "mainTaxon": "\/api\/v2\/shop\/taxons\/CATEGORY", + "productDraftTaxons": [ + { + "@type": "DraftTaxon", + "uuid": "@string@", + "taxon": "\/api\/v2\/shop\/taxons\/MUG", + "position": 1 + } + ] + }, + "product": null, + "lastVerifiedAt": null +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_send_to_verification_by_owner_vendor.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_send_to_verification_by_owner_vendor.json new file mode 100644 index 0000000..438aa4e --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_send_to_verification_by_owner_vendor.json @@ -0,0 +1,62 @@ +{ + "@context": "/api/v2/contexts/Listing", + "@id": "/api/v2/shop/account/vendor/product-listings/@string@", + "@type": "Listing", + "uuid": "@string@", + "code": "product_listing_bruce_1", + "enabled": true, + "verificationStatus": "under_verification", + "latestDraft": { + "@id": "/api/v2/shop/account/vendor/product-drafts/@string@", + "@type": "Draft", + "uuid": "@string@", + "code": "product_draft_bruce_1", + "status": "under_verification", + "verifiedAt": null, + "publishedAt": "@string@.isDateTime()", + "images": [], + "translations": { + "en_US": { + "@id": "/api/v2/shop/account/vendor/product-draft\/translations/@string@", + "@type": "DraftTranslation", + "uuid": "@string@", + "name": "product_draft_bruce_1_translations_us", + "slug": "product_draft_bruce_1_translations_us", + "description": null, + "metaKeywords": null, + "metaDescription": null, + "shortDescription": null, + "locale": "en_US" + } + }, + "productListingPrices": { + "CODE": { + "@type": "ListingPrice", + "uuid": "@string@", + "price": 100, + "originalPrice": 80, + "minimumPrice": 90, + "channelCode": "CODE" + } + }, + "attributes": [ + { + "@type": "DraftAttributeValue", + "uuid": "@string@", + "attribute": "/api/v2/shop/account/vendor/product-draft/attributes/@string@", + "value": "example value" + } + ], + "mainTaxon": "/api/v2/shop/taxons/CATEGORY", + "productDraftTaxons": [ + { + "@type": "DraftTaxon", + "uuid": "@string@", + "taxon": "/api/v2/shop/taxons/MUG", + "position": 1 + } + ] + }, + "product": null, + "lastVerifiedAt": null +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_validates_not_blank_product_draft_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_validates_not_blank_product_draft_response.json new file mode 100644 index 0000000..1f57aee --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_it_validates_not_blank_product_draft_response.json @@ -0,0 +1,13 @@ +{ + "@context": "\/api\/v2\/contexts\/ConstraintViolationList", + "@type": "ConstraintViolationList", + "hydra:title": "An error occurred", + "hydra:description": "productDraft: This field cannot be empty", + "violations": [ + { + "propertyPath": "productDraft", + "message": "This field cannot be empty", + "code": "@string@" + } + ] +} \ No newline at end of file diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_update_product_listing_by_vendor_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_update_product_listing_by_vendor_response.json new file mode 100644 index 0000000..de1c952 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductListingTest/test_update_product_listing_by_vendor_response.json @@ -0,0 +1,62 @@ +{ + "@context": "/api/v2/contexts/Listing", + "@id": "/api/v2/shop/account/vendor/product-listings/@string@", + "@type": "Listing", + "uuid": "@string@", + "code": "product_listing_bruce_1", + "enabled": true, + "verificationStatus": "created", + "latestDraft": { + "@id": "/api/v2/shop/account/vendor/product-drafts/@string@", + "@type": "Draft", + "uuid": "@string@", + "code": "product_draft_bruce_1", + "status": "created", + "images": [], + "verifiedAt": null, + "publishedAt": null, + "translations": { + "en_US": { + "@id": "/api/v2/shop/account/vendor/product-draft/translations/@string@", + "@type": "DraftTranslation", + "uuid": "@string@", + "locale": "en_US", + "name": "Changed name", + "slug": "Changed slug", + "description": "Changed description", + "metaKeywords": "Test metaKeywords", + "metaDescription": "Test metaDescription", + "shortDescription": "Test shortDescription" + } +}, + "productListingPrices": { + "CODE": { + "@type": "ListingPrice", + "uuid": "@string@", + "price": 120, + "originalPrice": 110, + "minimumPrice": 115, + "channelCode": "CODE" + } + }, + "attributes": [ + { + "@type": "DraftAttributeValue", + "uuid": "@string@", + "attribute": "/api/v2/shop/account/vendor/product-draft/attributes/@string@", + "value": "changed value" + } + ], + "mainTaxon": "/api/v2/shop/taxons/SECOND_CATEGORY", + "productDraftTaxons": [ + { + "@type": "DraftTaxon", + "uuid": "@string@", + "taxon": "/api/v2/shop/taxons/HAT", + "position": 2 + } + ] + }, + "product": null, + "lastVerifiedAt": null +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductVariant/InventoryTest/test_amount_validator_update_product_variant_by_vendor.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductVariant/InventoryTest/test_amount_validator_update_product_variant_by_vendor.json new file mode 100644 index 0000000..fbf3e0d --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductVariant/InventoryTest/test_amount_validator_update_product_variant_by_vendor.json @@ -0,0 +1,13 @@ +{ + "@context": "\/api\/v2\/contexts\/ConstraintViolationList", + "@type": "ConstraintViolationList", + "hydra:title": "An error occurred", + "hydra:description": "amount: On hand must be greater than the number of on hold units", + "violations": [ + { + "propertyPath": "amount", + "message": "On hand must be greater than the number of on hold units", + "code": "@string@" + } + ] +} \ No newline at end of file diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductVariant/InventoryTest/test_it_get_product_variant_by_vendor.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductVariant/InventoryTest/test_it_get_product_variant_by_vendor.json new file mode 100644 index 0000000..e1c18f2 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductVariant/InventoryTest/test_it_get_product_variant_by_vendor.json @@ -0,0 +1,10 @@ +{ + "@context": "\/api\/v2\/contexts\/ProductVariant", + "@id": "\/api\/v2\/shop\/product-variants\/bruce_1_2", + "@type": "ProductVariant", + "onHold": 0, + "amount": 1, + "tracked": true, + "code": "bruce_1_2", + "position": 1 +} \ No newline at end of file diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductVariant/InventoryTest/test_it_get_product_variants_by_vendor.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductVariant/InventoryTest/test_it_get_product_variants_by_vendor.json new file mode 100644 index 0000000..12268d6 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductVariant/InventoryTest/test_it_get_product_variants_by_vendor.json @@ -0,0 +1,35 @@ +{ + "@context": "\/api\/v2\/contexts\/ProductVariant", + "@id": "\/api\/v2\/shop\/product-variants", + "@type": "hydra:Collection", + "hydra:member": [ + { + "@id": "\/api\/v2\/shop\/product-variants\/bruce_1_1", + "@type": "ProductVariant", + "onHold": 2, + "amount": 3, + "tracked": true, + "code": "bruce_1_1", + "position": 0 + }, + { + "@id": "\/api\/v2\/shop\/product-variants\/bruce_1_2", + "@type": "ProductVariant", + "onHold": 0, + "amount": 1, + "tracked": true, + "code": "bruce_1_2", + "position": 1 + }, + { + "@id": "\/api\/v2\/shop\/product-variants\/bruce_2_1", + "@type": "ProductVariant", + "onHold": 0, + "amount": 0, + "tracked": false, + "code": "bruce_2_1", + "position": 0 + } + ], + "hydra:totalItems": 3 +} \ No newline at end of file diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductVariant/InventoryTest/test_it_update_product_variant_by_vendor.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductVariant/InventoryTest/test_it_update_product_variant_by_vendor.json new file mode 100644 index 0000000..c554409 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/ProductVariant/InventoryTest/test_it_update_product_variant_by_vendor.json @@ -0,0 +1,10 @@ +{ + "@context": "\/api\/v2\/contexts\/ProductVariant", + "@id": "\/api\/v2\/shop\/product-variants\/bruce_2_1", + "@type": "ProductVariant", + "onHold": 0, + "amount": 5, + "tracked": true, + "code": "bruce_2_1", + "position": 0 +} \ No newline at end of file diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorConversation/test_validate_not_blank_category_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorConversation/test_validate_not_blank_category_response.json new file mode 100644 index 0000000..761ac9e --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorConversation/test_validate_not_blank_category_response.json @@ -0,0 +1,13 @@ +{ + "@context": "\/api\/v2\/contexts\/ConstraintViolationList", + "@type": "ConstraintViolationList", + "hydra:title": "An error occurred", + "hydra:description": "category: This value should not be blank.", + "violations": [ + { + "propertyPath": "category", + "message": "This value should not be blank.", + "code": "c1051bb4-d103-4f74-8988-acbcafc7fdc3" + } + ] +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_it_get_shop_vendor_data_for_shop_user.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_it_get_shop_vendor_data_for_shop_user.json new file mode 100644 index 0000000..b05c317 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_it_get_shop_vendor_data_for_shop_user.json @@ -0,0 +1,10 @@ +{ + "@context": "\/api\/v2\/contexts\/Vendor", + "@id": "\/api\/v2\/shop\/vendors\/@string@", + "@type": "Vendor", + "uuid": "@string@", + "companyName": "Wayne Enterprises, Inc.", + "slug": "Wayne-Enterprises-Inc", + "image": null, + "backgroundImage": null +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_it_gets_vendor_data_for_shop_user_in_his_vendor_context.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_it_gets_vendor_data_for_shop_user_in_his_vendor_context.json new file mode 100644 index 0000000..bba1656 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_it_gets_vendor_data_for_shop_user_in_his_vendor_context.json @@ -0,0 +1,21 @@ +{ + "@context": "\/api\/v2\/contexts\/Vendor", + "@id": "\/api\/v2\/shop\/vendors\/@string@", + "@type": "Vendor", + "uuid": "@string@", + "companyName": "Wayne Enterprises, Inc.", + "taxIdentifier": "1234567", + "bankAccountNumber": "PL31109024026812185484588836", + "phoneNumber": "555123123", + "vendorAddress": { + "@type": "Address", + "country": "\/api\/v2\/shop\/countries\/US", + "city": "Arkham City", + "street": "Avenue 2115", + "postalCode": "00000" + }, + "slug": "Wayne-Enterprises-Inc", + "description": "description", + "image": null, + "backgroundImage": null +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_it_successful_update_vendor_data_for_shop_user_in_his_vendor_context.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_it_successful_update_vendor_data_for_shop_user_in_his_vendor_context.json new file mode 100644 index 0000000..4978d3d --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_it_successful_update_vendor_data_for_shop_user_in_his_vendor_context.json @@ -0,0 +1,21 @@ +{ + "@context": "\/api\/v2\/contexts\/Vendor", + "@id": "\/api\/v2\/shop\/vendors\/@string@", + "@type": "Vendor", + "uuid": "@string@", + "companyName": "Wayne Enterprises", + "taxIdentifier": "345", + "bankAccountNumber": "PL14109024029586826934815556", + "phoneNumber": "123456789", + "vendorAddress": { + "@type": "Address", + "country": "\/api\/v2\/shop\/countries\/PL", + "city": "New York", + "street": "Wall St. 1", + "postalCode": "12123" + }, + "slug": "Wayne-Enterprises", + "description": "Wayne Enterprises Desc", + "image": null, + "backgroundImage": null +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_not_blank_validation_rules.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_not_blank_validation_rules.json new file mode 100644 index 0000000..f624562 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_not_blank_validation_rules.json @@ -0,0 +1,55 @@ +{ + "@context": "\/api\/v2\/contexts\/ConstraintViolationList", + "@type": "ConstraintViolationList", + "hydra:title": "An error occurred", + "hydra:description": "taxIdentifier: This field cannot be empty\ntaxIdentifier: Required length: 3 characters.\nbankAccountNumber: This field cannot be empty\ncompanyName: This field cannot be empty\ncompanyName: Required length: 3 characters.\nphoneNumber: This field cannot be empty\nphoneNumber: Required length: 3 characters.\ndescription: This field cannot be empty\ndescription: Required length: 3 characters.", + + + "violations": [ + { + "propertyPath": "taxIdentifier", + "message": "This field cannot be empty", + "code": "@string@" + }, + { + "propertyPath": "taxIdentifier", + "message": "Required length: 3 characters.", + "code": "@string@" + }, + { + "propertyPath": "bankAccountNumber", + "message": "This field cannot be empty", + "code": "@string@" + }, + { + "propertyPath": "companyName", + "message": "This field cannot be empty", + "code": "@string@" + }, + { + "propertyPath": "companyName", + "message": "Required length: 3 characters.", + "code": "@string@" + }, + { + "propertyPath": "phoneNumber", + "message": "This field cannot be empty", + "code": "@string@" + }, + { + "propertyPath": "phoneNumber", + "message": "Required length: 3 characters.", + "code": "@string@" + }, + { + "propertyPath": "description", + "message": "This field cannot be empty", + "code": "@string@" + }, + { + "propertyPath": "description", + "message": "Required length: 3 characters.", + "code": "@string@" + } + ] +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_not_blank_vendor_image_file_validation_rule.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_not_blank_vendor_image_file_validation_rule.json new file mode 100644 index 0000000..784957c --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_not_blank_vendor_image_file_validation_rule.json @@ -0,0 +1,13 @@ +{ + "@context": "\/api\/v2\/contexts\/ConstraintViolationList", + "@type": "ConstraintViolationList", + "hydra:title": "An error occurred", + "hydra:description": "file: This field cannot be empty", + "violations": [ + { + "propertyPath": "file", + "message": "This field cannot be empty", + "code": "@string@" + } + ] +} \ No newline at end of file diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_not_blank_vendor_image_owner_validation_rule.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_not_blank_vendor_image_owner_validation_rule.json new file mode 100644 index 0000000..fd535ab --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_not_blank_vendor_image_owner_validation_rule.json @@ -0,0 +1,13 @@ +{ + "@context": "\/api\/v2\/contexts\/ConstraintViolationList", + "@type": "ConstraintViolationList", + "hydra:title": "An error occurred", + "hydra:description": "owner: This field cannot be empty", + "violations": [ + { + "propertyPath": "owner", + "message": "This field cannot be empty", + "code": "@string@" + } + ] +} \ No newline at end of file diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_vendor_image_upload_successfully.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_vendor_image_upload_successfully.json new file mode 100644 index 0000000..6050643 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/test_vendor_image_upload_successfully.json @@ -0,0 +1,8 @@ +{ + "@context": "\/api\/v2\/contexts\/VendorLogo", + "@id": "\/api\/v2\/shop\/account\/vendor\/logo\/@string@", + "@type": "VendorLogo", + "uuid": "@string@", + "path": "@string@\/avatar.png", + "owner": "\/api\/v2\/shop\/vendors\/@string@" +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/vendor_not_found_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/vendor_not_found_response.json new file mode 100644 index 0000000..523a62f --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorProfileTest/vendor_not_found_response.json @@ -0,0 +1,4 @@ +{ + "code": 500, + "message": "Item not found for \u0022\/api\/v2\/shop\/account\/vendors\/@string@\u0022." +} \ No newline at end of file diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/existed_vendor_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/existed_vendor_response.json new file mode 100644 index 0000000..1003088 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/existed_vendor_response.json @@ -0,0 +1,13 @@ +{ + "@context": "\/api\/v2\/contexts\/ConstraintViolationList", + "@type": "ConstraintViolationList", + "hydra:title": "An error occurred", + "hydra:description": "Vendor for current user already exists", + "violations": [ + { + "propertyPath": "", + "message": "Vendor for current user already exists", + "code": null + } + ] +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/max_length_validation_errors_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/max_length_validation_errors_response.json new file mode 100644 index 0000000..086256d --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/max_length_validation_errors_response.json @@ -0,0 +1,43 @@ +{ + "@context": "\/api\/v2\/contexts\/ConstraintViolationList", + "@type": "ConstraintViolationList", + "hydra:title": "An error occurred", + "hydra:description": "taxIdentifier: This field cannot be longer than 255\ncompanyName: This field cannot be longer than 255\nphoneNumber: This field cannot be longer than 255\ndescription: This field cannot be longer than 2048\nvendorAddress.city: This field cannot be longer than 255\nvendorAddress.street: This field cannot be longer than 255\nvendorAddress.postalCode: This field cannot be longer than 255", + "violations": [ + { + "propertyPath": "taxIdentifier", + "message": "This field cannot be longer than 255", + "code": "@string@" + }, + { + "propertyPath": "companyName", + "message": "This field cannot be longer than 255", + "code": "@string@" + }, + { + "propertyPath": "phoneNumber", + "message": "This field cannot be longer than 255", + "code": "@string@" + }, + { + "propertyPath": "description", + "message": "This field cannot be longer than 2048", + "code": "@string@" + }, + { + "propertyPath": "vendorAddress.city", + "message": "This field cannot be longer than 255", + "code": "@string@" + }, + { + "propertyPath": "vendorAddress.street", + "message": "This field cannot be longer than 255", + "code": "@string@" + }, + { + "propertyPath": "vendorAddress.postalCode", + "message": "This field cannot be longer than 255", + "code": "@string@" + } + ] +} \ No newline at end of file diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/min_length_validation_errors_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/min_length_validation_errors_response.json new file mode 100644 index 0000000..b78b1e9 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/min_length_validation_errors_response.json @@ -0,0 +1,43 @@ +{ + "@context": "\/api\/v2\/contexts\/ConstraintViolationList", + "@type": "ConstraintViolationList", + "hydra:title": "An error occurred", + "hydra:description": "taxIdentifier: Required length: 3 characters.\ncompanyName: Required length: 3 characters.\nphoneNumber: Required length: 3 characters.\ndescription: Required length: 3 characters.\nvendorAddress.city: Required length: 3 characters.\nvendorAddress.street: Required length: 3 characters.\nvendorAddress.postalCode: Required length: 3 characters.", + "violations": [ + { + "propertyPath": "taxIdentifier", + "message": "Required length: 3 characters.", + "code": "@string@" + }, + { + "propertyPath": "companyName", + "message": "Required length: 3 characters.", + "code": "@string@" + }, + { + "propertyPath": "phoneNumber", + "message": "Required length: 3 characters.", + "code": "@string@" + }, + { + "propertyPath": "description", + "message": "Required length: 3 characters.", + "code": "@string@" + }, + { + "propertyPath": "vendorAddress.city", + "message": "Required length: 3 characters.", + "code": "@string@" + }, + { + "propertyPath": "vendorAddress.street", + "message": "Required length: 3 characters.", + "code": "@string@" + }, + { + "propertyPath": "vendorAddress.postalCode", + "message": "Required length: 3 characters.", + "code": "@string@" + } + ] +} \ No newline at end of file diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/not_blank_address_fields_validation_errors_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/not_blank_address_fields_validation_errors_response.json new file mode 100644 index 0000000..159252d --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/not_blank_address_fields_validation_errors_response.json @@ -0,0 +1,28 @@ +{ + "@context": "\/api\/v2\/contexts\/ConstraintViolationList", + "@type": "ConstraintViolationList", + "hydra:title": "An error occurred", + "hydra:description": "vendorAddress.country: This field cannot be empty\nvendorAddress.city: This field cannot be empty\nvendorAddress.street: This field cannot be empty\nvendorAddress.postalCode: This field cannot be empty", + "violations": [ + { + "propertyPath": "vendorAddress.country", + "message": "This field cannot be empty", + "code": "@string@" + }, + { + "propertyPath": "vendorAddress.city", + "message": "This field cannot be empty", + "code": "@string@" + }, + { + "propertyPath": "vendorAddress.street", + "message": "This field cannot be empty", + "code": "@string@" + }, + { + "propertyPath": "vendorAddress.postalCode", + "message": "This field cannot be empty", + "code": "@string@" + } + ] +} \ No newline at end of file diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/not_blank_validation_errors_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/not_blank_validation_errors_response.json new file mode 100644 index 0000000..ea8ce85 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/not_blank_validation_errors_response.json @@ -0,0 +1,4 @@ +{ + "code": 400, + "message": "Request does not have the following required fields specified: companyName, taxIdentifier, bankAccountNumber, phoneNumber, description, vendorAddress." +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/success_registration_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/success_registration_response.json new file mode 100644 index 0000000..e4b290f --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/success_registration_response.json @@ -0,0 +1,21 @@ +{ + "@context": "\/api\/v2\/contexts\/Vendor", + "@id": "\/api\/v2\/shop\/vendors\/@string@", + "@type": "Vendor", + "uuid": "@string@", + "companyName": "Wayland Corp", + "taxIdentifier": "345", + "bankAccountNumber": "PL10109024026243964796978514", + "phoneNumber": "123456789", + "vendorAddress": { + "@type": "Address", + "country": "\/api\/v2\/shop\/countries\/PL", + "city": "Warszawa", + "street": "Jasna 1", + "postalCode": "12-123" + }, + "slug": "Wayland-Corp", + "description": "Wayland Corp Desc", + "image": null, + "backgroundImage": null +} diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/unauthorized_registration_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/unauthorized_registration_response.json new file mode 100644 index 0000000..40bf1d2 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/VendorRegistrationTest/unauthorized_registration_response.json @@ -0,0 +1,4 @@ +{ + "code": 401, + "message": "JWT Token not found" +} \ No newline at end of file diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/access_denied_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/access_denied_response.json new file mode 100644 index 0000000..fb8544e --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/access_denied_response.json @@ -0,0 +1,6 @@ +{ + "@context": "/api/v2/contexts/Error", + "@type": "hydra:Error", + "hydra:title": "An error occurred", + "hydra:description": "Access Denied." +} \ No newline at end of file diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/empty_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/empty_response.json new file mode 100644 index 0000000..e69de29 diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/internal_server_error.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/internal_server_error.json new file mode 100644 index 0000000..0d8e60d --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/internal_server_error.json @@ -0,0 +1,6 @@ +{ + "@context": "/api/v2/contexts/Error", + "@type": "hydra:Error", + "hydra:title": "An error occurred", + "hydra:description": "Internal Server Error" +} \ No newline at end of file diff --git a/OpenMarketplace/tests/Functional/Responses/Expected/Api/not_found_response.json b/OpenMarketplace/tests/Functional/Responses/Expected/Api/not_found_response.json new file mode 100644 index 0000000..5343641 --- /dev/null +++ b/OpenMarketplace/tests/Functional/Responses/Expected/Api/not_found_response.json @@ -0,0 +1,6 @@ +{ + "@context": "/api/v2/contexts/Error", + "@type": "hydra:Error", + "hydra:title": "An error occurred", + "hydra:description": "Not Found" +} \ No newline at end of file diff --git a/OpenMarketplace/tests/Integration/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/CustomerFilterStrategyTest.php b/OpenMarketplace/tests/Integration/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/CustomerFilterStrategyTest.php new file mode 100644 index 0000000..9776efa --- /dev/null +++ b/OpenMarketplace/tests/Integration/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/CustomerFilterStrategyTest.php @@ -0,0 +1,58 @@ +getContainer()->get('doctrine.orm.entity_manager'); + $this->customerRepository = $entityManager->getRepository(Customer::class); + $this->vendorRepository = $entityManager->getRepository(Vendor::class); + } + + public function test_supported_class(): void + { + $customerFilterStrategy = new CustomerFilterStrategy(); + $result = $customerFilterStrategy->supports(CustomerInterface::class); + + self::assertTrue($result); + } + + public function test_unsupported_class(): void + { + $customerFilterStrategy = new CustomerFilterStrategy(); + $result = $customerFilterStrategy->supports(OrderInterface::class); + + self::assertFalse($result); + } + + public function test_it_filters_resources(): void + { + $this->loadFixturesFromFile('VendorContextStrategy/CustomerFilterStrategyTest/customer_filter_strategy.yaml'); + + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + $queryBuilder = $this->customerRepository->createQueryBuilder('o'); + + $customerFilterStrategy = new customerFilterStrategy(); + $customerFilterStrategy->filterByVendor($queryBuilder, $vendor); + + $result = $queryBuilder->getQuery()->getResult(); + self::assertCount(2, $result); + } +} diff --git a/OpenMarketplace/tests/Integration/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/ProductDraftFilterStrategyTest.php b/OpenMarketplace/tests/Integration/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/ProductDraftFilterStrategyTest.php new file mode 100644 index 0000000..37401cb --- /dev/null +++ b/OpenMarketplace/tests/Integration/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/ProductDraftFilterStrategyTest.php @@ -0,0 +1,58 @@ +getContainer()->get('doctrine.orm.entity_manager'); + $this->productDraftRepository = $entityManager->getRepository(Draft::class); + $this->vendorRepository = $entityManager->getRepository(Vendor::class); + } + + public function test_supported_class(): void + { + $productDraftFilterStrategy = new ProductDraftFilterStrategy(); + $result = $productDraftFilterStrategy->supports(DraftInterface::class); + + self::assertTrue($result); + } + + public function test_unsupported_class(): void + { + $productDraftFilterStrategy = new ProductDraftFilterStrategy(); + $result = $productDraftFilterStrategy->supports(ListingInterface::class); + + self::assertFalse($result); + } + + public function test_it_filters_resources(): void + { + $this->loadFixturesFromFile('VendorContextStrategy/ProductDraftFilterStrategyTest/product_draft_filter_strategy.yaml'); + + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + $queryBuilder = $this->productDraftRepository->createQueryBuilder('o'); + + $productDraftFilterStrategy = new ProductDraftFilterStrategy(); + $productDraftFilterStrategy->filterByVendor($queryBuilder, $vendor); + + $result = $queryBuilder->getQuery()->getResult(); + self::assertCount(2, $result); + } +} diff --git a/OpenMarketplace/tests/Integration/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/ProductVariantFilterStrategyTest.php b/OpenMarketplace/tests/Integration/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/ProductVariantFilterStrategyTest.php new file mode 100644 index 0000000..0bd828b --- /dev/null +++ b/OpenMarketplace/tests/Integration/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/ProductVariantFilterStrategyTest.php @@ -0,0 +1,58 @@ +getContainer()->get('doctrine.orm.entity_manager'); + $this->productVariantRepository = $entityManager->getRepository(ProductVariant::class); + $this->vendorRepository = $entityManager->getRepository(Vendor::class); + } + + public function test_supported_class(): void + { + $productVariantFilterStrategy = new ProductVariantFilterStrategy(); + $result = $productVariantFilterStrategy->supports(ProductVariantInterface::class); + + self::assertTrue($result); + } + + public function test_unsupported_class(): void + { + $productVariantFilterStrategy = new ProductVariantFilterStrategy(); + $result = $productVariantFilterStrategy->supports(ProductInterface::class); + + self::assertFalse($result); + } + + public function test_it_filters_resources(): void + { + $this->loadFixturesFromFile('VendorContextStrategy/ProductVariantFilterStrategyTest/product_variant_filter_strategy.yaml'); + + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + $queryBuilder = $this->productVariantRepository->createQueryBuilder('o'); + + $productVariantFilterStrategy = new ProductVariantFilterStrategy(); + $productVariantFilterStrategy->filterByVendor($queryBuilder, $vendor); + + $result = $queryBuilder->getQuery()->getResult(); + self::assertCount(3, $result); + } +} diff --git a/OpenMarketplace/tests/Integration/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/VendorFilterStrategyTest.php b/OpenMarketplace/tests/Integration/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/VendorFilterStrategyTest.php new file mode 100644 index 0000000..cdae679 --- /dev/null +++ b/OpenMarketplace/tests/Integration/Api/Doctrine/QueryExtension/Vendor/VendorContextStrategy/VendorFilterStrategyTest.php @@ -0,0 +1,67 @@ +getContainer()->get('doctrine.orm.entity_manager'); + $this->draftAttributeRepository = $entityManager->getRepository(DraftAttribute::class); + $this->vendorRepository = $entityManager->getRepository(Vendor::class); + } + + public function test_supported_class_optional_vendor_aware(): void + { + $vendorFilterStrategy = new VendorFilterStrategy(); + $result = $vendorFilterStrategy->supports(OptionalVendorAwareInterface::class); + + self::assertTrue($result); + } + + public function test_supported_class_vendor_aware(): void + { + $vendorFilterStrategy = new VendorFilterStrategy(); + $result = $vendorFilterStrategy->supports(VendorAwareInterface::class); + + self::assertTrue($result); + } + + public function test_unsupported_class(): void + { + $vendorFilterStrategy = new VendorFilterStrategy(); + $result = $vendorFilterStrategy->supports(ProductVariantInterface::class); + + self::assertFalse($result); + } + + public function test_it_filters_resources(): void + { + $this->loadFixturesFromFile('VendorContextStrategy/VendorFilterStrategyTest/vendor_filter_strategy.yaml'); + + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + $queryBuilder = $this->draftAttributeRepository->createQueryBuilder('o'); + + $vendorFilterStrategy = new VendorFilterStrategy(); + $vendorFilterStrategy->filterByVendor($queryBuilder, $vendor); + + $result = $queryBuilder->getQuery()->getResult(); + self::assertCount(2, $result); + } +} diff --git a/OpenMarketplace/tests/Integration/Cli/SettlementGenerateCommandTest.php b/OpenMarketplace/tests/Integration/Cli/SettlementGenerateCommandTest.php new file mode 100644 index 0000000..083c4a3 --- /dev/null +++ b/OpenMarketplace/tests/Integration/Cli/SettlementGenerateCommandTest.php @@ -0,0 +1,278 @@ +find('bitbag:settlement:generate'); + $this->commandTester = new CommandTester($command); + $this->settlementRepository = self::getContainer()->get('open_marketplace.repository.settlement'); + $this->vendorRepository = self::getContainer()->get('bitbag.open_marketplace.component.vendor.repository.vendor'); + $this->channelRepository = self::getContainer()->get('sylius.repository.channel'); + $this->orderRepository = self::getContainer()->get('sylius.repository.order'); + } + + public function test_it_throws_exception_if_period_resolver_for_settlement_frequency_does_not_exist(): void + { + $this->loadFixturesFromFile('SettlementGenerateCommandTest/test_it_throws_exception_if_period_resolver_for_settlement_frequency_does_not_exist.yaml'); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Could not find period resolver for vendor with settlement frequency "daily"'); + $this->commandTester->execute([]); + } + + public function test_it_generates_settlements_for_all_vendors(): void + { + $this->loadFixturesFromFile('SettlementGenerateCommandTest/test_it_generates_settlements_for_all_vendors.yaml'); + $this->assertCount(0, $this->settlementRepository->findAll()); + $this->commandTester->execute([]); + $this->commandTester->assertCommandIsSuccessful(); + $vendorWeyland = $this->vendorRepository->findOneBySlug('Weyland-Corp'); + $vendorWayne = $this->vendorRepository->findOneBySlug('Wayne-Enterprises-Inc'); + $vendorTommy = $this->vendorRepository->findOneBySlug('Tommy-Corp'); + $channelEu = $this->channelRepository->findOneBy(['code' => 'EU']); + $channelUs = $this->channelRepository->findOneBy(['code' => 'US']); + $settlementsVendorWeyland = $this->settlementRepository->findBy(['vendor' => $vendorWeyland]); + $settlementsVendorWayne = $this->settlementRepository->findBy(['vendor' => $vendorWayne]); + $settlementsVendorTommy = $this->settlementRepository->findBy(['vendor' => $vendorTommy]); + [$weeklyStartDate, $weeklyEndDate] = $this->getStartAndEndDate('weekly'); + [$monthlyStartDate, $monthlyEndDate] = $this->getStartAndEndDate('monthly'); + [$quarterlyStartDate, $quarterlyEndDate] = $this->getStartAndEndDate('quarterly'); + + $this->assertCount(2, $settlementsVendorWayne); + $this->assertSettlementSame( + [ + 'totalAmount' => 540, + 'totalCommissionAmount' => 35, + 'startDate' => $monthlyStartDate, + 'endDate' => $monthlyEndDate, + 'channel' => $channelUs, + ], + $settlementsVendorWayne[0] + ); + $this->assertSettlementSame( + [ + 'totalAmount' => 1002, + 'totalCommissionAmount' => 70, + 'startDate' => $monthlyStartDate, + 'endDate' => $monthlyEndDate, + 'channel' => $channelEu, + ], + $settlementsVendorWayne[1] + ); + + $this->assertCount(2, $settlementsVendorWeyland); + $this->assertSettlementSame( + [ + 'totalAmount' => 0, + 'totalCommissionAmount' => 0, + 'startDate' => $weeklyStartDate, + 'endDate' => $weeklyEndDate, + 'channel' => $channelUs, + ], + $settlementsVendorWeyland[0] + ); + $this->assertSettlementSame( + [ + 'totalAmount' => 700, + 'totalCommissionAmount' => 100, + 'startDate' => $weeklyStartDate, + 'endDate' => $weeklyEndDate, + 'channel' => $channelEu, + ], + $settlementsVendorWeyland[1] + ); + + $this->assertCount(2, $settlementsVendorTommy); + $this->assertSettlementSame( + [ + 'totalAmount' => 400, + 'totalCommissionAmount' => 10, + 'startDate' => $quarterlyStartDate, + 'endDate' => $quarterlyEndDate, + 'channel' => $channelUs, + ], + $settlementsVendorTommy[0] + ); + $this->assertSettlementSame( + [ + 'totalAmount' => 0, + 'totalCommissionAmount' => 0, + 'startDate' => $quarterlyStartDate, + 'endDate' => $quarterlyEndDate, + 'channel' => $channelEu, + ], + $settlementsVendorTommy[1] + ); + } + + public function test_it_not_generates_settlements_for_if_settlement_already_exist(): void + { + $this->loadFixturesFromFile('SettlementGenerateCommandTest/test_it_not_generates_settlements_for_if_settlement_already_exist.yaml'); + $settlements = $this->settlementRepository->findAll(); + $vendorWeyland = $this->vendorRepository->findOneBySlug('Weyland-Corp'); + $vendorWayne = $this->vendorRepository->findOneBySlug('Wayne-Enterprises-Inc'); + $channelEu = $this->channelRepository->findOneBy(['code' => 'EU']); + $channelUs = $this->channelRepository->findOneBy(['code' => 'US']); + [$startDate, $endDate] = $this->getStartAndEndDate('weekly'); + $this->assertCount(1, $settlements); + $this->assertSettlementSame( + [ + 'totalAmount' => 1002, + 'totalCommissionAmount' => 70, + 'startDate' => $startDate, + 'endDate' => $endDate, + 'channel' => $channelEu, + ], + $settlements[0] + ); + + $this->commandTester->execute([]); + $this->commandTester->assertCommandIsSuccessful(); + $settlementsVendorWeyland = $this->settlementRepository->findBy(['vendor' => $vendorWeyland]); + $settlementsVendorWayne = $this->settlementRepository->findBy(['vendor' => $vendorWayne]); + $this->assertCount(2, $settlementsVendorWayne); + $this->assertSame($settlements[0], $settlementsVendorWayne[0]); + $this->assertSettlementSame( + [ + 'totalAmount' => 540, + 'totalCommissionAmount' => 35, + 'startDate' => $startDate, + 'endDate' => $endDate, + 'channel' => $channelUs, + ], + $settlementsVendorWayne[1] + ); + + $this->assertCount(2, $settlementsVendorWeyland); + $this->assertSettlementSame( + [ + 'totalAmount' => 0, + 'totalCommissionAmount' => 0, + 'startDate' => $startDate, + 'endDate' => $endDate, + 'channel' => $channelUs, + ], + $settlementsVendorWeyland[0] + ); + $this->assertSettlementSame( + [ + 'totalAmount' => 700, + 'totalCommissionAmount' => 100, + 'startDate' => $startDate, + 'endDate' => $endDate, + 'channel' => $channelEu, + ], + $settlementsVendorWeyland[1] + ); + } + + public function test_it_generates_settlements_for_incomplete_period(): void + { + $this->loadFixturesFromFile('SettlementGenerateCommandTest/test_it_generates_settlements_for_incomplete_period.yaml'); + $settlements = $this->settlementRepository->findAll(); + $vendorWayne = $this->vendorRepository->findOneBySlug('Wayne-Enterprises-Inc'); + $channelUs = $this->channelRepository->findOneBy(['code' => 'US']); + $channelEu = $this->channelRepository->findOneBy(['code' => 'EU']); + + [$startDate, $endDate] = $this->getStartAndEndDate('weekly'); + + /** @var OrderInterface $lastWayneOrder */ + $lastWayneOrder = $this->orderRepository->findOneBy(['vendor' => $vendorWayne], ['paidAt' => 'DESC']); + + $to = \DateTime::createFromInterface($lastWayneOrder->getPaidAt())->modify('- 1 hour'); + $from = new \DateTime('last week monday'); + + $settlement = $settlements[0]; + $settlement->setStartDate($from); + $settlement->setEndDate($to); + + $this->assertSettlementSame( + [ + 'totalAmount' => 1002, + 'totalCommissionAmount' => 70, + 'startDate' => $from, + 'endDate' => $to, + 'channel' => $channelEu, + ], + $settlement + ); + + $this->getEntityManager()->flush(); + + $this->commandTester->execute([]); + $this->commandTester->assertCommandIsSuccessful(); + $settlementsVendorWayne = $this->settlementRepository->findBy(['vendor' => $vendorWayne]); + $this->assertCount(3, $settlementsVendorWayne); + $this->assertSame($settlements[0], $settlementsVendorWayne[0]); + $this->assertSettlementSame( + [ + 'totalAmount' => 0, + 'totalCommissionAmount' => 0, + 'startDate' => $startDate, + 'endDate' => $endDate, + 'channel' => $channelUs, + ], + $settlementsVendorWayne[1] + ); + + $this->assertSettlementSame( + [ + 'totalAmount' => 540, + 'totalCommissionAmount' => 35, + 'startDate' => \DateTime::createFromInterface($settlement->getEndDate())->modify('+ 1 second'), + 'endDate' => $endDate, + 'channel' => $channelEu, + ], + $settlementsVendorWayne[2] + ); + } + + private function getStartAndEndDate(string $frequency): array + { + return match ($frequency) { + 'weekly' => [ + new \DateTime('last week monday 00:00:00'), + new \DateTime('last week sunday 23:59:59'), + ], + 'monthly' => [ + new \DateTime('first day of last month 00:00:00'), + new \DateTime('last day of last month 23:59:59'), + ], + 'quarterly' => [ + (new \DateTime())->setTimestamp(QuarterlySettlementPeriodResolver::getLastQuarterStartDate()), + (new \DateTime())->setTimestamp(QuarterlySettlementPeriodResolver::getLastQuarterEndDate()), + ], + }; + } + + private function assertSettlementSame(array $expected, SettlementInterface $actual): void + { + $this->assertSame($expected['totalAmount'], $actual->getTotalAmount()); + $this->assertSame($expected['totalCommissionAmount'], $actual->getTotalCommissionAmount()); + $this->assertSame($expected['startDate']->getTimestamp(), $actual->getStartDate()->getTimestamp()); + $this->assertSame($expected['endDate']->getTimestamp(), $actual->getEndDate()->getTimestamp()); + $this->assertSame($expected['channel'], $actual->getChannel()); + } +} diff --git a/OpenMarketplace/tests/Integration/Converter/AttributesConverterTest.php b/OpenMarketplace/tests/Integration/Converter/AttributesConverterTest.php new file mode 100644 index 0000000..28b48d1 --- /dev/null +++ b/OpenMarketplace/tests/Integration/Converter/AttributesConverterTest.php @@ -0,0 +1,43 @@ +entityManager = $this->getContainer() + ->get('doctrine') + ->getManager() + ; + + $this->attributesConverter = $this->getContainer()->get('bitbag.open_marketplace.component.product_listing.draft_converter.operator.attributes'); + } + + public function test_it_removes_attributes_from_product(): void + { + $this->loadFixturesFromFile('AttributesConverterTest/test_it_removes_attributes_from_product.yaml'); + $draft = $this->entityManager->getRepository(Draft::class)->findAll()[0]; + + $productListing = $draft->getProductListing(); + $product = $productListing->getProduct(); + + $this->assertCount(1, $product->getAttributes()); + + $this->attributesConverter->convert($draft, $product); + $this->entityManager->flush(); + + $freshProduct = $this->entityManager->getRepository(Product::class)->findAll()[0]; + $this->entityManager->refresh($freshProduct); + + $this->assertCount(0, $freshProduct->getAttributes()); + } +} diff --git a/OpenMarketplace/tests/Integration/Custom/Vendor/BackgroundImageCascadesTest.php b/OpenMarketplace/tests/Integration/Custom/Vendor/BackgroundImageCascadesTest.php new file mode 100644 index 0000000..9361da9 --- /dev/null +++ b/OpenMarketplace/tests/Integration/Custom/Vendor/BackgroundImageCascadesTest.php @@ -0,0 +1,42 @@ +entityManager = $this->getContainer()->get('doctrine.orm.entity_manager'); + $this->vendorRepository = $this->entityManager->getRepository(Vendor::class); + + $this->backgroundImageRepository = $this->entityManager->getRepository(BackgroundImage::class); + } + + public function test_it_removes_background_image_only(): void + { + $this->loadFixturesFromFile('BackgroundImageCascadesTest/cascade_tests.yaml'); + + /** @var VendorInterface $vendor */ + $vendor = $this->vendorRepository->findOneBy(['slug' => 'Weyland-Corp']); + /** @var BackgroundImage $vendorImage */ + $vendorImage = $this->backgroundImageRepository->findOneBy(['owner' => $vendor]); + $this->backgroundImageRepository->remove($vendorImage); + + self::assertSame($vendor->getSlug(), 'Weyland-Corp'); + } +} diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/AttributesConverterTest/test_it_removes_attributes_from_product.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/AttributesConverterTest/test_it_removes_attributes_from_product.yaml new file mode 100644 index 0000000..65008f5 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/AttributesConverterTest/test_it_removes_attributes_from_product.yaml @@ -0,0 +1,88 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'oliver@queen.com' + emailCanonical: 'oliver@queen.com' + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@wayne.co' + emailCanonical: 'bruce.wayne@wayne.co' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_bruce' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@vendor_address' + slug: 'someslug' + description: 'description' + commission: 10 + commissionType: 'net' +Sylius\Component\Product\Model\ProductAttributeTranslation: + attributeTranslation1: + locale: de + name: 'Becher Sammlung' + translatable: '@productAttribute1' + attributeTranslation2: + locale: en_US + name: 'Mug collection' + translatable: '@productAttribute1' +Sylius\Component\Product\Model\ProductAttribute: + productAttribute1: + translatable: true + fallbackLocale: en_US + currentLocale: de + code: mug_material + type: text + storage_type: text + translations: + - '@attributeTranslation1' + - '@attributeTranslation2' +Sylius\Component\Product\Model\ProductAttributeValue: + test_value: + subject: '@some_product' + attribute: '@productAttribute1' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttribute: + attribute: + vendor: '@vendor_oliver' + storage_type: 'text' + code: 'test_code' + productAttribute: '@productAttribute1' +BitBag\OpenMarketPlace\Component\Product\Entity\Product: + some_product: + code: 'test_code' + vendor: '@vendor_oliver' + attributes: + - '@test_value' +BitBag\OpenMarketPlace\Component\ProductListing\Entity\Listing: + test_listing: + code: 'test_code' + vendor: '@vendor_oliver' + product: '@some_product' +BitBag\OpenMarketPlace\Component\ProductListing\Entity\Draft: + some_draft: + code: 'test_code' + productListing: '@test_listing' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/BackgroundImageCascadesTest/cascade_tests.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/BackgroundImageCascadesTest/cascade_tests.yaml new file mode 100644 index 0000000..7b4ae82 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/BackgroundImageCascadesTest/cascade_tests.yaml @@ -0,0 +1,111 @@ +Sylius\Component\Addressing\Model\Country: + country_pl: + code: 'PL' + country_us: + code: 'US' +Sylius\Component\Addressing\Model\Zone: + zone_us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_us: + code: 'US' + belongsTo: '@zone_us' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel: + code: 'CODE' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' + customer_peter: + firstName: 'Peter' + lastName: 'Weyland' + email: 'peter.weyland@example.com' + emailCanonical: 'peter.weyland@example.com' + customer_john: + firstName: 'John' + lastName: 'Smith' + email: 'john.smith@example.com' + emailCanonical: 'john.smith@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + usernameCanonical: 'bruce.wayne@example.com' + user_peter: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_peter' + username: 'peter.weyland@example.com' + usernameCanonical: 'peter.weyland@example.com' + user_john: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_john' + username: 'john.smith@example.com' + usernameCanonical: 'john.smith@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address_bruce: + country: '@country_us' + city: 'Arkham City' + postalCode: '00000' + street: 'Avenue 2115' + vendor_address_peter: + country: '@country_us' + city: 'San Francisco' + postalCode: '94016' + street: 'Unknown 1' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '555123123' + vendorAddress: '@vendor_address_bruce' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL14109024029586826934815556' + phoneNumber: '555444333' + vendorAddress: '@vendor_address_peter' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Vendor\Entity\LogoImage: + vendor_image_peter: + owner: '@vendor_peter' + path: '/dummy/file/path' +BitBag\OpenMarketplace\Component\Vendor\Entity\BackgroundImage: + vendor_backgroundimage_peter: + owner: '@vendor_peter' + path: '/dummy/file/path' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/ChannelRepositoryTest/test_it_finds_all_enabled_channels.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ChannelRepositoryTest/test_it_finds_all_enabled_channels.yaml new file mode 100644 index 0000000..17e72ae --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ChannelRepositoryTest/test_it_finds_all_enabled_channels.yaml @@ -0,0 +1,32 @@ +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Core\Model\Channel: + channel_us: + code: 'US' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true + channel_de: + code: 'DE' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true + channel_disabled: + code: 'disabled' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: false diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/ChannelRepositoryTest/test_it_finds_enabled_channel_by_code.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ChannelRepositoryTest/test_it_finds_enabled_channel_by_code.yaml new file mode 100644 index 0000000..70e6e54 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ChannelRepositoryTest/test_it_finds_enabled_channel_by_code.yaml @@ -0,0 +1,16 @@ +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Core\Model\Channel: + channel_us: + code: 'US' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/ConversationRepositoryTest/test_it_finds_all_conversations_with_status_and_user.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ConversationRepositoryTest/test_it_finds_all_conversations_with_status_and_user.yaml new file mode 100644 index 0000000..bdb83e5 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ConversationRepositoryTest/test_it_finds_all_conversations_with_status_and_user.yaml @@ -0,0 +1,57 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'oliver@queen.com' + emailCanonical: 'oliver@queen.com' + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@wayne.co' + emailCanonical: 'bruce.wayne@wayne.co' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_bruce' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@vendor_address' + slug: 'someslug' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Messaging\Entity\Conversation: + opened_conversation_with_oliver: + shopUser: '@user_oliver' + status: 'open' + closed_conversation_with_oliver: + shopUser: '@user_oliver' + status: 'closed' + opened_conversation_with_bruce: + shopUser: '@user_bruce' + status: 'open' + closed_conversation_with_bruce: + shopUser: '@user_bruce' + status: 'closed' + diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/CustomerRepositoryTest/test_it_finds_all_customers_of_vendor.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/CustomerRepositoryTest/test_it_finds_all_customers_of_vendor.yaml new file mode 100644 index 0000000..de3c19b --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/CustomerRepositoryTest/test_it_finds_all_customers_of_vendor.yaml @@ -0,0 +1,77 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'test@example.com' + emailCanonical: 'test2@example.com' + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'test2@example.com' + emailCanonical: 'test@example.com' + customer_clark: + firstName: 'Clark' + lastName: 'Kent' + email: 'test3@example.com' + emailCanonical: 'test3@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + username: 'oliver@queen.com' + usernameCanonical: 'oliver@queen.com' + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce@wayne.com' + usernameCanonical: 'bruce@wayne.com' + user_clark: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_clark' + username: 'clark@kent.com' + usernameCanonical: 'clark@kent.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@vendor_address' + slug: 'oliver-queen-company' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + first_product: + vendor: '@vendor_oliver' + code: 'code' +Sylius\Component\Core\Model\ProductVariant: + first_variant: + product: '@first_product' + code: 'code' +BitBag\OpenMarketplace\Component\Order\Entity\Order: + bruce_order_made_with_oliver: + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_oliver' + customer: '@customer_bruce' + clarks_order_made_with_random_vendor: + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_clark' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/CustomerRepositoryTest/test_it_finds_order_for_vendor.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/CustomerRepositoryTest/test_it_finds_order_for_vendor.yaml new file mode 100644 index 0000000..de3c19b --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/CustomerRepositoryTest/test_it_finds_order_for_vendor.yaml @@ -0,0 +1,77 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'test@example.com' + emailCanonical: 'test2@example.com' + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'test2@example.com' + emailCanonical: 'test@example.com' + customer_clark: + firstName: 'Clark' + lastName: 'Kent' + email: 'test3@example.com' + emailCanonical: 'test3@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + username: 'oliver@queen.com' + usernameCanonical: 'oliver@queen.com' + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce@wayne.com' + usernameCanonical: 'bruce@wayne.com' + user_clark: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_clark' + username: 'clark@kent.com' + usernameCanonical: 'clark@kent.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@vendor_address' + slug: 'oliver-queen-company' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + first_product: + vendor: '@vendor_oliver' + code: 'code' +Sylius\Component\Core\Model\ProductVariant: + first_variant: + product: '@first_product' + code: 'code' +BitBag\OpenMarketplace\Component\Order\Entity\Order: + bruce_order_made_with_oliver: + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_oliver' + customer: '@customer_bruce' + clarks_order_made_with_random_vendor: + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_clark' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/DraftAttributeRepositoryTest/test_it_finds_all_draft_attributes_for_given_vendor.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/DraftAttributeRepositoryTest/test_it_finds_all_draft_attributes_for_given_vendor.yaml new file mode 100644 index 0000000..2d78526 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/DraftAttributeRepositoryTest/test_it_finds_all_draft_attributes_for_given_vendor.yaml @@ -0,0 +1,117 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel: + code: 'code' + name: 'name' + default_locale: '@locale' + tax_calculation_strategy: 'order_items_based' + base_currency: '@dollar' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'test@example.com' + emailCanonical: 'test2@example.com' + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'test2@example.com' + emailCanonical: 'test@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + username: 'oliver@queen.com' + usernameCanonical: 'oliver@queen.com' + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce@wayne.com' + usernameCanonical: 'bruce@wayne.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + oliver_vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' + bruce_vendor_address: + country: '@poland' + city: 'Poznan' + postalCode: '61-512' + street: 'Umultowska 54' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@oliver_vendor_address' + slug: 'oliver-queen-company' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@bruce_vendor_address' + slug: 'bruce-wayne-company' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttributeTranslation: + translation1: + translatable: '@first_olivers_attribute' + name: 'name1' + locale: '@locale' + translation2: + translatable: '@second_olivers_attribute' + name: 'name2' + locale: '@locale' + translation3: + translatable: '@first_bruces_attribute' + name: 'name3' + locale: '@locale' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttribute: + first_olivers_attribute: + addTranslation: '@translation1' + currentLocale: '@locale' + vendor: '@vendor_oliver' + code: 'testcode1' + name: 'testname1' + type: 'checkbox' + storage_type: 'boolean' + translatable: false + second_olivers_attribute: + addTranslation: '@translation2' + currentLocale: '@locale' + vendor: '@vendor_oliver' + code: 'testcode2' + name: 'testname2' + type: 'checkbox' + storage_type: 'boolean' + first_bruces_attribute: + addTranslation: '@translation3' + currentLocale: '@locale' + vendor: '@vendor_bruce' + code: 'testcode3' + name: 'testname3' + type: 'checkbox' + storage_type: 'boolean' + diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_counts_order_for_settlement.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_counts_order_for_settlement.yaml new file mode 100644 index 0000000..04952d3 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_counts_order_for_settlement.yaml @@ -0,0 +1,312 @@ +Sylius\Component\Addressing\Model\Country: + country_pl: + code: 'PL' + country_us: + code: 'US' +Sylius\Component\Addressing\Model\Zone: + zone_us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_us: + code: 'US' + belongsTo: '@zone_us' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel_us: + code: 'US' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true +Sylius\Component\Core\Model\ShippingMethod: + shipping_method_ups: + code: 'ups' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: [ '@channel_us' ] + configuration: + CODE: + amount: 5 + shipping_method_fedex: + code: 'fedex' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: [ '@channel_us' ] + configuration: + CODE: + amount: 5 +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' + customer_peter: + firstName: 'Peter' + lastName: 'Weyland' + email: 'peter.weyland@example.com' + emailCanonical: 'peter.weyland@example.com' + customer_john: + firstName: 'John' + lastName: 'Smith' + email: 'john.smith@example.com' + emailCanonical: 'john.smith@example.com' + phoneNumber: 123456789 +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + usernameCanonical: 'bruce.wayne@example.com' + user_peter: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_peter' + username: 'peter.weyland@example.com' + usernameCanonical: 'peter.weyland@example.com' + user_john: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_john' + username: 'john.smith@example.com' + usernameCanonical: 'john.smith@example.com' +Sylius\Component\Core\Model\Address: + address_john: + firstName: 'John' + lastName: 'Smith' + countryCode: 'US' + city: 'Arkham City' + postcode: '00000' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL31109024026812185484588836' + phoneNumber: '555123123' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + createdAt: '' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL17109024022586255711928552' + phoneNumber: '555444333' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + product_bruce_1: + vendor: '@vendor_bruce' + code: 'bruce_1' + enabled: true + channels: [ '@channel_us' ] + product_peter_1: + vendor: '@vendor_peter' + code: 'peter_2' + enabled: true + channels: [ '@channel_us' ] +Sylius\Component\Core\Model\ProductVariant: + product_variant_product_bruce_1_1: + product: '@product_bruce_1' + code: 'bruce_1_1' + enabled: true + onHold: 2 + onHand: 3 + tracked: true + product_variant_product_bruce_1_2: + product: '@product_bruce_1' + code: 'bruce_1_2' + enabled: true + onHand: 1 + tracked: true + product_variant_product_peter_1_1: + product: '@product_peter_1' + code: 'peter_1_1' + enabled: true + onHand: 3 + tracked: true +Sylius\Component\Core\Model\ChannelPricing: + pricing_product_variant_product_bruce_1_1_us: + price: 10 + originalPrice: 15 + minimumPrice: 0 + channelCode: 'US' + productVariant: '@product_variant_product_bruce_1_1' + pricing_product_variant_product_bruce_1_2_us: + price: 13 + originalPrice: 25 + minimumPrice: 10 + channelCode: 'US' + productVariant: '@product_variant_product_bruce_1_2' + pricing_product_variant_product_peter_1_1_us: + price: 9 + originalPrice: 12 + minimumPrice: 5 + channelCode: 'US' + productVariant: '@product_variant_product_peter_1_1' +BitBag\OpenMarketplace\Component\Order\Entity\Order: + bruce_order_made_by_john_1_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_1_main' + channel: '@channel_us' + bruce_order_made_by_john_1: + primaryOrder: '@bruce_order_made_by_john_1_main' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_bruce' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_1' + shippingAddress: '@address_john' + billingAddress: '@address_john' + paid_at: '' + commission_total: 35 + channel: '@channel_us' + bruce_order_made_by_john_2_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_2_main' + paid_at: '' + channel: '@channel_us' + bruce_order_made_by_john_2: + primaryOrder: '@bruce_order_made_by_john_2_main' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_bruce' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_2' + paid_at: '' + commission_total: 70 + channel: '@channel_us' + peter_order_made_by_john_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'peter_order_made_by_john_main' + channel: '@channel_us' + peter_order_made_by_john: + primaryOrder: '@peter_order_made_by_john' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_peter' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'peter_order_made_by_john' + paid_at: '' + commission_total: 100 + channel: '@channel_us' + order_made_by_peter_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_peter' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'order_made_by_peter_main' + channel: '@channel_us' + order_made_by_peter: + primaryOrder: '@order_made_by_peter_main' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_peter' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'order_made_by_peter' + paid_at: '' + commission_total: 10 + channel: '@channel_us' +BitBag\OpenMarketplace\Component\Order\Entity\OrderItem: + bruce_order_made_by_john_1_item_1: + order: '@bruce_order_made_by_john_1' + variant: '@product_variant_product_bruce_1_1' + unit_price: 540 + bruce_order_made_by_john_2_item_1: + order: '@bruce_order_made_by_john_2' + variant: '@product_variant_product_bruce_1_2' + unit_price: 1002 + peter_order_made_by_john_1_item_1: + order: '@peter_order_made_by_john' + variant: '@product_variant_product_peter_1_1' + unit_price: 700 +BitBag\OpenMarketplace\Component\Order\Entity\Shipment: + bruce_order_made_by_john_1_shipment: + vendor: '@vendor_bruce' + order: '@bruce_order_made_by_john_1' + method: '@shipping_method_ups' + bruce_order_made_by_john_2_shipment: + vendor: '@vendor_bruce' + order: '@bruce_order_made_by_john_2' + method: '@shipping_method_fedex' + peter_order_made_by_john_shipment: + vendor: '@vendor_peter' + order: '@peter_order_made_by_john' + method: '@shipping_method_ups' +Sylius\Component\Core\Model\OrderItemUnit: + bruce_order_made_by_john_1_item_1_unit: + __construct: [ '@bruce_order_made_by_john_1_item_1' ] + shipment: '@bruce_order_made_by_john_1_shipment' + bruce_order_made_by_john_2_item_1_unit: + __construct: [ '@bruce_order_made_by_john_2_item_1' ] + shipment: '@bruce_order_made_by_john_2_shipment' + peter_order_made_by_john_1_item_1_unit: + __construct: [ '@peter_order_made_by_john_1_item_1' ] + shipment: '@peter_order_made_by_john_shipment' +BitBag\OpenMarketplace\Component\Settlement\Entity\Settlement: + vendor_bruce_settlement: + vendor: '@vendor_bruce' + total_amount: 1002 + total_commission_amount: 70 + start_date: '' + end_date: '' + channel: '@channel_us' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_create_query_builder_to_find_order_for_settlement.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_create_query_builder_to_find_order_for_settlement.yaml new file mode 100644 index 0000000..04952d3 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_create_query_builder_to_find_order_for_settlement.yaml @@ -0,0 +1,312 @@ +Sylius\Component\Addressing\Model\Country: + country_pl: + code: 'PL' + country_us: + code: 'US' +Sylius\Component\Addressing\Model\Zone: + zone_us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_us: + code: 'US' + belongsTo: '@zone_us' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel_us: + code: 'US' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true +Sylius\Component\Core\Model\ShippingMethod: + shipping_method_ups: + code: 'ups' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: [ '@channel_us' ] + configuration: + CODE: + amount: 5 + shipping_method_fedex: + code: 'fedex' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: [ '@channel_us' ] + configuration: + CODE: + amount: 5 +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' + customer_peter: + firstName: 'Peter' + lastName: 'Weyland' + email: 'peter.weyland@example.com' + emailCanonical: 'peter.weyland@example.com' + customer_john: + firstName: 'John' + lastName: 'Smith' + email: 'john.smith@example.com' + emailCanonical: 'john.smith@example.com' + phoneNumber: 123456789 +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + usernameCanonical: 'bruce.wayne@example.com' + user_peter: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_peter' + username: 'peter.weyland@example.com' + usernameCanonical: 'peter.weyland@example.com' + user_john: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_john' + username: 'john.smith@example.com' + usernameCanonical: 'john.smith@example.com' +Sylius\Component\Core\Model\Address: + address_john: + firstName: 'John' + lastName: 'Smith' + countryCode: 'US' + city: 'Arkham City' + postcode: '00000' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL31109024026812185484588836' + phoneNumber: '555123123' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + createdAt: '' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL17109024022586255711928552' + phoneNumber: '555444333' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + product_bruce_1: + vendor: '@vendor_bruce' + code: 'bruce_1' + enabled: true + channels: [ '@channel_us' ] + product_peter_1: + vendor: '@vendor_peter' + code: 'peter_2' + enabled: true + channels: [ '@channel_us' ] +Sylius\Component\Core\Model\ProductVariant: + product_variant_product_bruce_1_1: + product: '@product_bruce_1' + code: 'bruce_1_1' + enabled: true + onHold: 2 + onHand: 3 + tracked: true + product_variant_product_bruce_1_2: + product: '@product_bruce_1' + code: 'bruce_1_2' + enabled: true + onHand: 1 + tracked: true + product_variant_product_peter_1_1: + product: '@product_peter_1' + code: 'peter_1_1' + enabled: true + onHand: 3 + tracked: true +Sylius\Component\Core\Model\ChannelPricing: + pricing_product_variant_product_bruce_1_1_us: + price: 10 + originalPrice: 15 + minimumPrice: 0 + channelCode: 'US' + productVariant: '@product_variant_product_bruce_1_1' + pricing_product_variant_product_bruce_1_2_us: + price: 13 + originalPrice: 25 + minimumPrice: 10 + channelCode: 'US' + productVariant: '@product_variant_product_bruce_1_2' + pricing_product_variant_product_peter_1_1_us: + price: 9 + originalPrice: 12 + minimumPrice: 5 + channelCode: 'US' + productVariant: '@product_variant_product_peter_1_1' +BitBag\OpenMarketplace\Component\Order\Entity\Order: + bruce_order_made_by_john_1_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_1_main' + channel: '@channel_us' + bruce_order_made_by_john_1: + primaryOrder: '@bruce_order_made_by_john_1_main' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_bruce' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_1' + shippingAddress: '@address_john' + billingAddress: '@address_john' + paid_at: '' + commission_total: 35 + channel: '@channel_us' + bruce_order_made_by_john_2_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_2_main' + paid_at: '' + channel: '@channel_us' + bruce_order_made_by_john_2: + primaryOrder: '@bruce_order_made_by_john_2_main' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_bruce' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_2' + paid_at: '' + commission_total: 70 + channel: '@channel_us' + peter_order_made_by_john_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'peter_order_made_by_john_main' + channel: '@channel_us' + peter_order_made_by_john: + primaryOrder: '@peter_order_made_by_john' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_peter' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'peter_order_made_by_john' + paid_at: '' + commission_total: 100 + channel: '@channel_us' + order_made_by_peter_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_peter' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'order_made_by_peter_main' + channel: '@channel_us' + order_made_by_peter: + primaryOrder: '@order_made_by_peter_main' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_peter' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'order_made_by_peter' + paid_at: '' + commission_total: 10 + channel: '@channel_us' +BitBag\OpenMarketplace\Component\Order\Entity\OrderItem: + bruce_order_made_by_john_1_item_1: + order: '@bruce_order_made_by_john_1' + variant: '@product_variant_product_bruce_1_1' + unit_price: 540 + bruce_order_made_by_john_2_item_1: + order: '@bruce_order_made_by_john_2' + variant: '@product_variant_product_bruce_1_2' + unit_price: 1002 + peter_order_made_by_john_1_item_1: + order: '@peter_order_made_by_john' + variant: '@product_variant_product_peter_1_1' + unit_price: 700 +BitBag\OpenMarketplace\Component\Order\Entity\Shipment: + bruce_order_made_by_john_1_shipment: + vendor: '@vendor_bruce' + order: '@bruce_order_made_by_john_1' + method: '@shipping_method_ups' + bruce_order_made_by_john_2_shipment: + vendor: '@vendor_bruce' + order: '@bruce_order_made_by_john_2' + method: '@shipping_method_fedex' + peter_order_made_by_john_shipment: + vendor: '@vendor_peter' + order: '@peter_order_made_by_john' + method: '@shipping_method_ups' +Sylius\Component\Core\Model\OrderItemUnit: + bruce_order_made_by_john_1_item_1_unit: + __construct: [ '@bruce_order_made_by_john_1_item_1' ] + shipment: '@bruce_order_made_by_john_1_shipment' + bruce_order_made_by_john_2_item_1_unit: + __construct: [ '@bruce_order_made_by_john_2_item_1' ] + shipment: '@bruce_order_made_by_john_2_shipment' + peter_order_made_by_john_1_item_1_unit: + __construct: [ '@peter_order_made_by_john_1_item_1' ] + shipment: '@peter_order_made_by_john_shipment' +BitBag\OpenMarketplace\Component\Settlement\Entity\Settlement: + vendor_bruce_settlement: + vendor: '@vendor_bruce' + total_amount: 1002 + total_commission_amount: 70 + start_date: '' + end_date: '' + channel: '@channel_us' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_finds_all_vendor_orders.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_finds_all_vendor_orders.yaml new file mode 100644 index 0000000..de3c19b --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_finds_all_vendor_orders.yaml @@ -0,0 +1,77 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'test@example.com' + emailCanonical: 'test2@example.com' + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'test2@example.com' + emailCanonical: 'test@example.com' + customer_clark: + firstName: 'Clark' + lastName: 'Kent' + email: 'test3@example.com' + emailCanonical: 'test3@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + username: 'oliver@queen.com' + usernameCanonical: 'oliver@queen.com' + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce@wayne.com' + usernameCanonical: 'bruce@wayne.com' + user_clark: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_clark' + username: 'clark@kent.com' + usernameCanonical: 'clark@kent.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@vendor_address' + slug: 'oliver-queen-company' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + first_product: + vendor: '@vendor_oliver' + code: 'code' +Sylius\Component\Core\Model\ProductVariant: + first_variant: + product: '@first_product' + code: 'code' +BitBag\OpenMarketplace\Component\Order\Entity\Order: + bruce_order_made_with_oliver: + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_oliver' + customer: '@customer_bruce' + clarks_order_made_with_random_vendor: + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_clark' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_finds_for_settlement.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_finds_for_settlement.yaml new file mode 100644 index 0000000..9f619bd --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_finds_for_settlement.yaml @@ -0,0 +1,332 @@ +Sylius\Component\Addressing\Model\Country: + country_pl: + code: 'PL' + country_us: + code: 'US' +Sylius\Component\Addressing\Model\Zone: + zone_us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_us: + code: 'US' + belongsTo: '@zone_us' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' + euro: + code: 'EUR' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel_us: + code: 'US' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true + channel_eu: + code: 'EU' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@euro' + enabled: true +Sylius\Component\Core\Model\ShippingMethod: + shipping_method_ups: + code: 'ups' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: [ '@channel_us', '@channel_eu' ] + configuration: + CODE: + amount: 5 + shipping_method_fedex: + code: 'fedex' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: [ '@channel_us', '@channel_eu' ] + configuration: + CODE: + amount: 5 +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' + customer_peter: + firstName: 'Peter' + lastName: 'Weyland' + email: 'peter.weyland@example.com' + emailCanonical: 'peter.weyland@example.com' + customer_john: + firstName: 'John' + lastName: 'Smith' + email: 'john.smith@example.com' + emailCanonical: 'john.smith@example.com' + phoneNumber: 123456789 +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + usernameCanonical: 'bruce.wayne@example.com' + user_peter: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_peter' + username: 'peter.weyland@example.com' + usernameCanonical: 'peter.weyland@example.com' + user_john: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_john' + username: 'john.smith@example.com' + usernameCanonical: 'john.smith@example.com' +Sylius\Component\Core\Model\Address: + address_john: + firstName: 'John' + lastName: 'Smith' + countryCode: 'US' + city: 'Arkham City' + postcode: '00000' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL31109024026812185484588836' + phoneNumber: '555123123' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL17109024022586255711928552' + phoneNumber: '555444333' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + product_bruce_1: + vendor: '@vendor_bruce' + code: 'bruce_1' + enabled: true + channels: [ '@channel_us', '@channel_eu' ] + product_peter_1: + vendor: '@vendor_peter' + code: 'peter_2' + enabled: true + channels: [ '@channel_us', '@channel_eu' ] +Sylius\Component\Core\Model\ProductVariant: + product_variant_product_bruce_1_1: + product: '@product_bruce_1' + code: 'bruce_1_1' + enabled: true + onHold: 2 + onHand: 3 + tracked: true + product_variant_product_bruce_1_2: + product: '@product_bruce_1' + code: 'bruce_1_2' + enabled: true + onHand: 1 + tracked: true + product_variant_product_peter_1_1: + product: '@product_peter_1' + code: 'peter_1_1' + enabled: true + onHand: 3 + tracked: true +Sylius\Component\Core\Model\ChannelPricing: + pricing_product_variant_product_bruce_1_1_us: + price: 10 + originalPrice: 15 + minimumPrice: 0 + channelCode: 'US' + productVariant: '@product_variant_product_bruce_1_1' + pricing_product_variant_product_bruce_1_2_us: + price: 13 + originalPrice: 25 + minimumPrice: 10 + channelCode: 'US' + productVariant: '@product_variant_product_bruce_1_2' + pricing_product_variant_product_peter_1_1_us: + price: 9 + originalPrice: 12 + minimumPrice: 5 + channelCode: 'US' + productVariant: '@product_variant_product_peter_1_1' + pricing_product_variant_product_bruce_1_1_eu: + price: 9 + originalPrice: 14 + minimumPrice: 0 + channelCode: 'EU' + productVariant: '@product_variant_product_bruce_1_1' + pricing_product_variant_product_bruce_1_2_eu: + price: 12 + originalPrice: 24 + minimumPrice: 9 + channelCode: 'EU' + productVariant: '@product_variant_product_bruce_1_2' + pricing_product_variant_product_peter_1_1_eu: + price: 8 + originalPrice: 11 + minimumPrice: 4 + channelCode: 'EU' + productVariant: '@product_variant_product_peter_1_1' +BitBag\OpenMarketplace\Component\Order\Entity\Order: + bruce_order_made_by_john_1_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_1_main' + channel: '@channel_us' + bruce_order_made_by_john_1: + primaryOrder: '@bruce_order_made_by_john_1_main' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_bruce' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_1' + shippingAddress: '@address_john' + billingAddress: '@address_john' + paid_at: '' + commission_total: 35 + channel: '@channel_us' + bruce_order_made_by_john_2_main: + mode: 'primary' + currency_code: 'EUR' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_2_main' + channel: '@channel_us' + bruce_order_made_by_john_2: + primaryOrder: '@bruce_order_made_by_john_2_main' + mode: 'secondary' + currency_code: 'EUR' + locale_code: 'en-US' + vendor: '@vendor_bruce' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_2' + paid_at: '' + commission_total: 70 + channel: '@channel_us' + peter_order_made_by_john_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'peter_order_made_by_john_main' + channel: '@channel_us' + peter_order_made_by_john: + primaryOrder: '@peter_order_made_by_john' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_peter' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'peter_order_made_by_john' + paid_at: '' + commission_total: 100 + channel: '@channel_us' + order_made_by_peter_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_peter' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'order_made_by_peter_main' + channel: '@channel_us' + order_made_by_peter: + primaryOrder: '@order_made_by_peter_main' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_peter' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'order_made_by_peter' + paid_at: '' + commission_total: 10 + channel: '@channel_us' +BitBag\OpenMarketplace\Component\Order\Entity\OrderItem: + bruce_order_made_by_john_1_item_1: + order: '@bruce_order_made_by_john_1' + variant: '@product_variant_product_bruce_1_1' + unit_price: 540 + bruce_order_made_by_john_2_item_1: + order: '@bruce_order_made_by_john_2' + variant: '@product_variant_product_bruce_1_2' + unit_price: 1002 + peter_order_made_by_john_1_item_1: + order: '@peter_order_made_by_john' + variant: '@product_variant_product_peter_1_1' + unit_price: 700 +BitBag\OpenMarketplace\Component\Order\Entity\Shipment: + bruce_order_made_by_john_1_shipment: + vendor: '@vendor_bruce' + order: '@bruce_order_made_by_john_1' + method: '@shipping_method_ups' + bruce_order_made_by_john_2_shipment: + vendor: '@vendor_bruce' + order: '@bruce_order_made_by_john_2' + method: '@shipping_method_fedex' + peter_order_made_by_john_shipment: + vendor: '@vendor_peter' + order: '@peter_order_made_by_john' + method: '@shipping_method_ups' +Sylius\Component\Core\Model\OrderItemUnit: + bruce_order_made_by_john_1_item_1_unit: + __construct: [ '@bruce_order_made_by_john_1_item_1' ] + shipment: '@bruce_order_made_by_john_1_shipment' + bruce_order_made_by_john_2_item_1_unit: + __construct: [ '@bruce_order_made_by_john_2_item_1' ] + shipment: '@bruce_order_made_by_john_2_shipment' + peter_order_made_by_john_1_item_1_unit: + __construct: [ '@peter_order_made_by_john_1_item_1' ] + shipment: '@peter_order_made_by_john_shipment' + + diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_finds_order_for_vendor.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_finds_order_for_vendor.yaml new file mode 100644 index 0000000..de3c19b --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_finds_order_for_vendor.yaml @@ -0,0 +1,77 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'test@example.com' + emailCanonical: 'test2@example.com' + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'test2@example.com' + emailCanonical: 'test@example.com' + customer_clark: + firstName: 'Clark' + lastName: 'Kent' + email: 'test3@example.com' + emailCanonical: 'test3@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + username: 'oliver@queen.com' + usernameCanonical: 'oliver@queen.com' + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce@wayne.com' + usernameCanonical: 'bruce@wayne.com' + user_clark: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_clark' + username: 'clark@kent.com' + usernameCanonical: 'clark@kent.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@vendor_address' + slug: 'oliver-queen-company' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + first_product: + vendor: '@vendor_oliver' + code: 'code' +Sylius\Component\Core\Model\ProductVariant: + first_variant: + product: '@first_product' + code: 'code' +BitBag\OpenMarketplace\Component\Order\Entity\Order: + bruce_order_made_with_oliver: + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_oliver' + customer: '@customer_bruce' + clarks_order_made_with_random_vendor: + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_clark' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_finds_orders_for_vendors_customer.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_finds_orders_for_vendors_customer.yaml new file mode 100644 index 0000000..de3c19b --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/OrderRepositoryTest/test_it_finds_orders_for_vendors_customer.yaml @@ -0,0 +1,77 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'test@example.com' + emailCanonical: 'test2@example.com' + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'test2@example.com' + emailCanonical: 'test@example.com' + customer_clark: + firstName: 'Clark' + lastName: 'Kent' + email: 'test3@example.com' + emailCanonical: 'test3@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + username: 'oliver@queen.com' + usernameCanonical: 'oliver@queen.com' + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce@wayne.com' + usernameCanonical: 'bruce@wayne.com' + user_clark: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_clark' + username: 'clark@kent.com' + usernameCanonical: 'clark@kent.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@vendor_address' + slug: 'oliver-queen-company' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + first_product: + vendor: '@vendor_oliver' + code: 'code' +Sylius\Component\Core\Model\ProductVariant: + first_variant: + product: '@first_product' + code: 'code' +BitBag\OpenMarketplace\Component\Order\Entity\Order: + bruce_order_made_with_oliver: + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_oliver' + customer: '@customer_bruce' + clarks_order_made_with_random_vendor: + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_clark' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductDraftFilesOperatorTest/test_it_copies_draft_images_to_product.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductDraftFilesOperatorTest/test_it_copies_draft_images_to_product.yaml new file mode 100644 index 0000000..c4e1ecc --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductDraftFilesOperatorTest/test_it_copies_draft_images_to_product.yaml @@ -0,0 +1,48 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'oliver@queen.com' + emailCanonical: 'oliver@queen.com' + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@wayne.co' + emailCanonical: 'bruce.wayne@wayne.co' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_bruce' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@vendor_address' + description: 'description' + slug: 'test-slug' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\ProductListing\Entity\Listing: + listing: + createdAt: '' + code: 'Test' + vendor: '@vendor_oliver' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductListingRepositoryTest/test_it_finds_product_listings_with_latest_draft.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductListingRepositoryTest/test_it_finds_product_listings_with_latest_draft.yaml new file mode 100644 index 0000000..d4440b1 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductListingRepositoryTest/test_it_finds_product_listings_with_latest_draft.yaml @@ -0,0 +1,87 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'test@example.com' + emailCanonical: 'test2@example.com' + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'test2@example.com' + emailCanonical: 'test@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + username: 'oliver@queen.com' + usernameCanonical: 'oliver@queen.com' + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce@wayne.com' + usernameCanonical: 'bruce@wayne.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + oliver_vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' + bruce_vendor_address: + country: '@poland' + city: 'Poznan' + postalCode: '61-512' + street: 'Umultowska 54' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@oliver_vendor_address' + slug: 'oliver-queen-company' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@bruce_vendor_address' + slug: 'bruce-wayne-company' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\ProductListing\Entity\Listing: + product_listing_oliver_1: + vendor: '@vendor_oliver' + code: 'Oliver product' + product_listing_oliver_2: + vendor: '@vendor_oliver' + code: 'Oliver product 2' + product_listing_bruce_1: + vendor: '@vendor_bruce' + code: 'Bruce product' +BitBag\OpenMarketplace\Component\ProductListing\Entity\Draft: + product_draft_oliver_1_1: + product_listing: '@product_listing_oliver_1' + version_number: '1' + product_draft_oliver_1_2: + product_listing: '@product_listing_oliver_1' + version_number: '2' + product_draft_oliver_2_1: + product_listing: '@product_listing_oliver_2' + version_number: '1' + product_draft_bruce_1: + product_listing: '@product_listing_bruce_1' + version_number: '1' + diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductListingRepositoryTest/test_it_finds_product_listings_with_latest_draft_by_vendor.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductListingRepositoryTest/test_it_finds_product_listings_with_latest_draft_by_vendor.yaml new file mode 100644 index 0000000..d4440b1 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductListingRepositoryTest/test_it_finds_product_listings_with_latest_draft_by_vendor.yaml @@ -0,0 +1,87 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'test@example.com' + emailCanonical: 'test2@example.com' + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'test2@example.com' + emailCanonical: 'test@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + username: 'oliver@queen.com' + usernameCanonical: 'oliver@queen.com' + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce@wayne.com' + usernameCanonical: 'bruce@wayne.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + oliver_vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' + bruce_vendor_address: + country: '@poland' + city: 'Poznan' + postalCode: '61-512' + street: 'Umultowska 54' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@oliver_vendor_address' + slug: 'oliver-queen-company' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@bruce_vendor_address' + slug: 'bruce-wayne-company' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\ProductListing\Entity\Listing: + product_listing_oliver_1: + vendor: '@vendor_oliver' + code: 'Oliver product' + product_listing_oliver_2: + vendor: '@vendor_oliver' + code: 'Oliver product 2' + product_listing_bruce_1: + vendor: '@vendor_bruce' + code: 'Bruce product' +BitBag\OpenMarketplace\Component\ProductListing\Entity\Draft: + product_draft_oliver_1_1: + product_listing: '@product_listing_oliver_1' + version_number: '1' + product_draft_oliver_1_2: + product_listing: '@product_listing_oliver_1' + version_number: '2' + product_draft_oliver_2_1: + product_listing: '@product_listing_oliver_2' + version_number: '1' + product_draft_bruce_1: + product_listing: '@product_listing_bruce_1' + version_number: '1' + diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductRepositoryTest/test_it_finds_vendor_products.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductRepositoryTest/test_it_finds_vendor_products.yaml new file mode 100644 index 0000000..6d11cc7 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductRepositoryTest/test_it_finds_vendor_products.yaml @@ -0,0 +1,139 @@ +Sylius\Component\Addressing\Model\Country: + USA: + code: 'US' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel: + code: 'code' + name: 'name' + locales: + - '@locale' + default_locale: '@locale' + tax_calculation_strategy: 'order_items_based' + base_currency: '@dollar' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'test@example.com' + emailCanonical: 'test2@example.com' + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'test2@example.com' + emailCanonical: 'test@example.com' + customer_clark: + firstName: 'Clark' + lastName: 'Kent' + email: 'test3@example.com' + emailCanonical: 'test3@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + username: 'oliver@queen.com' + usernameCanonical: 'oliver@queen.com' + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce@wayne.com' + usernameCanonical: 'bruce@wayne.com' + user_clark: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_clark' + username: 'clark@kent.com' + usernameCanonical: 'clark@kent.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address: + country: '@USA' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@vendor_address' + slug: 'oliver-queen-company' + description: 'description' + commission: 10 + commissionType: 'net' +Sylius\Component\Taxonomy\Model\TaxonTranslation: + taxon_translation: + locale: 'en_US' + name: 'dsa' + slug: 'dsa' +Sylius\Component\Core\Model\Taxon: + taxon: + code: 'menu_category' + translations: + - '@taxon_translation' + enabled: true +Sylius\Component\Core\Model\ProductTranslation: + first_product_US_translation: + name: 'test_name1' + slug: 'test_slug1' + locale: 'en_US' + second_product_US_translation: + name: 'test_name2' + slug: 'test_slug2' + locale: 'en_US' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + first_product: + mainTaxon: '@taxon' + vendor: '@vendor_oliver' + code: 'code' + channels: + - '@channel' + translations: + - '@first_product_US_translation' + second_product: + mainTaxon: '@taxon' + vendor: '@vendor_oliver' + code: 'code2' + channels: + - '@channel' + translations: + - '@second_product_US_translation' + third_product_without_translation: + mainTaxon: '@taxon' + vendor: '@vendor_oliver' + code: 'code3' + channels: + - '@channel' +Sylius\Component\Core\Model\ProductTaxon: + firs_relation: + taxon: '@taxon' + product: '@first_product' + second_relation: + taxon: '@taxon' + product: '@second_product' +Sylius\Component\Core\Model\ProductVariant: + first_variant: + product: '@first_product' + code: 'code' +BitBag\OpenMarketplace\Component\Order\Entity\Order: + bruce_order_made_with_oliver: + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_oliver' + customer: '@customer_bruce' + clarks_order_made_with_random_vendor: + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_clark' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductReviewRepositoryTest/found_product_reviews_for_vendor.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductReviewRepositoryTest/found_product_reviews_for_vendor.yaml new file mode 100644 index 0000000..d3c30bd --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductReviewRepositoryTest/found_product_reviews_for_vendor.yaml @@ -0,0 +1,93 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_adam: + firstName: 'Adam' + lastName: 'Ondra' + email: 'adam@example.com' + emailCanonical: 'adam@example.com' + customer_alex: + firstName: 'Alex' + lastName: 'Honnold' + email: 'alex@example.com' + emailCanonical: 'alex@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_adam: + plainPassword: 'password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_adam' + username: 'adam@ondra.com' + usernameCanonical: 'adam@ondara.com' + user_alex: + plainPassword: 'password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_alex' + username: 'alex@honnold.com' + usernameCanonical: 'alex@honnold.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_adam_address: + country: '@poland' + city: 'Poznan' + postalCode: '61-512' + street: 'Umultowska 54' + vendor_alex_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 20' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_adam: + shopUser: '@user_adam' + companyName: 'Skalnik' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@vendor_adam_address' + slug: 'adam-ondra-company' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_alex: + shopUser: '@user_alex' + companyName: '8a' + taxIdentifier: '7654321' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '123432234' + vendorAddress: '@vendor_alex_address' + slug: 'alex-honnold-company' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + product_adam_1: + vendor: '@vendor_adam' + code: 'Harness-adam' + product_adam_2: + vendor: '@vendor_adam' + code: 'Climbing boots-adam' + product_alex_1: + vendor: '@vendor_alex' + code: 'Harness-alex' +Sylius\Component\Core\Model\ProductReview: + first_product_review: + title: 'Product Review' + comment: 'comment' + rating: '3' + author: '@customer_alex' + reviewSubject: '@product_adam_1' + second_product_review: + title: 'Best Product Review' + comment: 'comment' + rating: '5' + author: '@customer_alex' + reviewSubject: '@product_adam_2' + third_product_review: + title: 'Good Product Review' + comment: 'comment' + rating: '4' + author: '@customer_adam' + reviewSubject: '@product_alex_1' + diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductReviewRepositoryTest/not_found_product_reviews_for_vendor.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductReviewRepositoryTest/not_found_product_reviews_for_vendor.yaml new file mode 100644 index 0000000..10c80c6 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/ProductReviewRepositoryTest/not_found_product_reviews_for_vendor.yaml @@ -0,0 +1,93 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_adam: + firstName: 'Adam' + lastName: 'Ondra' + email: 'adam@example.com' + emailCanonical: 'adam@example.com' + customer_alex: + firstName: 'Alex' + lastName: 'Honnold' + email: 'alex@example.com' + emailCanonical: 'alex@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_adam: + plainPassword: 'password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_adam' + username: 'adam@ondra.com' + usernameCanonical: 'adam@ondara.com' + user_alex: + plainPassword: 'password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_alex' + username: 'alex@honnold.com' + usernameCanonical: 'alex@honnold.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_adam_address: + country: '@poland' + city: 'Poznan' + postalCode: '61-512' + street: 'Umultowska 54' + vendor_alex_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 20' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_adam: + shopUser: '@user_adam' + companyName: 'Skalnik' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@vendor_adam_address' + slug: 'adam-ondra-company' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_alex: + shopUser: '@user_alex' + companyName: '8a' + taxIdentifier: '7654321' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '123432234' + vendorAddress: '@vendor_alex_address' + slug: 'alex-honnold-company' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + product_adam_1: + vendor: '@vendor_adam' + code: 'Harness-adam' + product_adam_2: + vendor: '@vendor_adam' + code: 'Climbing boots-adam' + product_alex_1: + vendor: '@vendor_alex' + code: 'Harness-alex' +Sylius\Component\Core\Model\ProductReview: + first_product_review: + title: 'Product Review' + comment: 'comment' + rating: '3' + author: '@customer_alex' + reviewSubject: '@product_adam_1' + second_product_review: + title: 'Best Product Review' + comment: 'comment' + rating: '5' + author: '@customer_alex' + reviewSubject: '@product_adam_2' + third_product_review: + title: 'Good Product Review' + comment: 'comment' + rating: '4' + author: '@customer_adam' + reviewSubject: '@product_adam_1' + diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementGenerateCommandTest/test_it_generates_settlements_for_all_vendors.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementGenerateCommandTest/test_it_generates_settlements_for_all_vendors.yaml new file mode 100644 index 0000000..ba1e990 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementGenerateCommandTest/test_it_generates_settlements_for_all_vendors.yaml @@ -0,0 +1,454 @@ +Sylius\Component\Addressing\Model\Country: + country_pl: + code: 'PL' + country_us: + code: 'US' +Sylius\Component\Addressing\Model\Zone: + zone_us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_us: + code: 'US' + belongsTo: '@zone_us' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' + euro: + code: 'EUR' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel_us: + code: 'US' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true + channel_eu: + code: 'EU' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@euro' + enabled: true +Sylius\Component\Core\Model\ShippingMethod: + shipping_method_ups: + code: 'ups' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: [ '@channel_us', '@channel_eu' ] + configuration: + CODE: + amount: 5 + shipping_method_fedex: + code: 'fedex' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: [ '@channel_us', '@channel_eu' ] + configuration: + CODE: + amount: 5 +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' + customer_peter: + firstName: 'Peter' + lastName: 'Weyland' + email: 'peter.weyland@example.com' + emailCanonical: 'peter.weyland@example.com' + customer_john: + firstName: 'John' + lastName: 'Smith' + email: 'john.smith@example.com' + emailCanonical: 'john.smith@example.com' + customer_tommy: + firstName: 'Tommy' + lastName: 'Mush' + email: 'tommy.mush@example.com' + emailCanonical: 'tommy.mush@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + usernameCanonical: 'bruce.wayne@example.com' + user_peter: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_peter' + username: 'peter.weyland@example.com' + usernameCanonical: 'peter.weyland@example.com' + user_john: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_john' + username: 'john.smith@example.com' + usernameCanonical: 'john.smith@example.com' + user_tommy: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_tommy' + username: 'tommy.mush@example.com' + usernameCanonical: 'tommy.mush@example.com' +Sylius\Component\Core\Model\Address: + address_john: + firstName: 'John' + lastName: 'Smith' + countryCode: 'US' + city: 'Arkham City' + postcode: '00000' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL31109024026812185484588836' + phoneNumber: '555123123' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + createdAt: '' + settlement_frequency: 'monthly' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL17109024022586255711928552' + phoneNumber: '555444333' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' + settlement_frequency: 'weekly' + vendor_tommy: + shopUser: '@user_tommy' + companyName: 'Tommy Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'NL78INGB4783095582' + phoneNumber: '555444333' + slug: 'Tommy-Corp' + description: 'description' + commission: 10 + commissionType: 'net' + settlement_frequency: 'quarterly' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + product_bruce_1: + vendor: '@vendor_bruce' + code: 'bruce_1' + enabled: true + channels: [ '@channel_us', '@channel_eu' ] + product_peter_1: + vendor: '@vendor_peter' + code: 'peter_1' + enabled: true + channels: [ '@channel_us', '@channel_eu' ] + product_tommy_1: + vendor: '@vendor_tommy' + code: 'tommy_1' + enabled: true + channels: [ '@channel_us', '@channel_eu' ] +Sylius\Component\Core\Model\ProductVariant: + product_variant_product_bruce_1_1: + product: '@product_bruce_1' + code: 'bruce_1_1' + enabled: true + tracked: false + product_variant_product_bruce_1_2: + product: '@product_bruce_1' + code: 'bruce_1_2' + enabled: true + tracked: false + product_variant_product_peter_1_1: + product: '@product_peter_1' + code: 'peter_1_1' + enabled: true + tracked: false + product_variant_product_tommy_1_1: + product: '@product_tommy_1' + code: 'tommy_1_1' + enabled: true + tracked: false +Sylius\Component\Core\Model\ChannelPricing: + pricing_product_variant_product_bruce_1_1_us: + price: 10 + originalPrice: 15 + minimumPrice: 0 + channelCode: 'US' + productVariant: '@product_variant_product_bruce_1_1' + pricing_product_variant_product_bruce_1_2_us: + price: 13 + originalPrice: 25 + minimumPrice: 10 + channelCode: 'US' + productVariant: '@product_variant_product_bruce_1_2' + pricing_product_variant_product_peter_1_1_us: + price: 9 + originalPrice: 12 + minimumPrice: 5 + channelCode: 'US' + productVariant: '@product_variant_product_peter_1_1' + pricing_product_variant_product_bruce_1_1_eu: + price: 9 + originalPrice: 14 + minimumPrice: 0 + channelCode: 'EU' + productVariant: '@product_variant_product_bruce_1_1' + pricing_product_variant_product_bruce_1_2_eu: + price: 12 + originalPrice: 24 + minimumPrice: 9 + channelCode: 'EU' + productVariant: '@product_variant_product_bruce_1_2' + pricing_product_variant_product_peter_1_1_eu: + price: 8 + originalPrice: 11 + minimumPrice: 4 + channelCode: 'EU' + productVariant: '@product_variant_product_peter_1_1' + pricing_product_variant_product_tommy_1_1_eu: + price: 20 + originalPrice: 50 + minimumPrice: 30 + channelCode: 'EU' + productVariant: '@product_variant_product_tommy_1_1' + pricing_product_variant_product_tommy_1_1_us: + price: 23 + originalPrice: 78 + minimumPrice: 45 + channelCode: 'US' + productVariant: '@product_variant_product_tommy_1_1' +BitBag\OpenMarketplace\Component\Order\Entity\Order: + bruce_order_made_by_john_1_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_1_main' + channel: '@channel_us' + bruce_order_made_by_john_1: + primaryOrder: '@bruce_order_made_by_john_1_main' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_bruce' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_1' + shippingAddress: '@address_john' + billingAddress: '@address_john' + paid_at: '' + commission_total: 35 + channel: '@channel_us' + bruce_order_made_by_john_2_main: + mode: 'primary' + currency_code: 'EUR' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_2_main' + channel: '@channel_eu' + bruce_order_made_by_john_2: + primaryOrder: '@bruce_order_made_by_john_2_main' + mode: 'secondary' + currency_code: 'EUR' + locale_code: 'en-US' + vendor: '@vendor_bruce' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_2' + paid_at: '' + commission_total: 70 + channel: '@channel_eu' + peter_order_made_by_john_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'peter_order_made_by_john_main' + channel: '@channel_eu' + peter_order_made_by_john: + primaryOrder: '@peter_order_made_by_john' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_peter' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'peter_order_made_by_john' + paid_at: '' + commission_total: 100 + channel: '@channel_eu' + tommy_order_made_by_peter_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_peter' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'tommy_order_made_by_peter_main' + channel: '@channel_us' + tommy_order_made_by_peter: + primaryOrder: '@tommy_order_made_by_peter_main' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_peter' + vendor: '@vendor_tommy' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'tommy_order_made_by_peter' + paid_at: '' + commission_total: 10 + channel: '@channel_us' + tommy_order_made_by_john_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'tommy_order_made_by_john_main' + channel: '@channel_us' + tommy_order_made_by_john: + primaryOrder: '@tommy_order_made_by_john_main' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_john' + vendor: '@vendor_tommy' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'tommy_order_made_by_john' + paid_at: '' + commission_total: 10 + channel: '@channel_us' + tommy_order_made_by_john_eu_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + channel: '@channel_eu' + tommy_order_made_by_john_eu: + primaryOrder: '@tommy_order_made_by_john_eu_main' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_tommy' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'tommy_order_made_by_john_eu' + paid_at: '' + commission_total: 55 + channel: '@channel_eu' +BitBag\OpenMarketplace\Component\Order\Entity\OrderItem: + bruce_order_made_by_john_1_item_1: + order: '@bruce_order_made_by_john_1' + variant: '@product_variant_product_bruce_1_1' + unit_price: 540 + bruce_order_made_by_john_2_item_1: + order: '@bruce_order_made_by_john_2' + variant: '@product_variant_product_bruce_1_2' + unit_price: 1002 + peter_order_made_by_john_1_item_1: + order: '@peter_order_made_by_john' + variant: '@product_variant_product_peter_1_1' + unit_price: 700 + tommy_order_made_by_john_eu_item_1: + order: '@tommy_order_made_by_john_eu' + variant: '@product_variant_product_tommy_1_1' + unit_price: 400 + tommy_order_made_by_peter_item_1: + order: '@tommy_order_made_by_peter' + variant: '@product_variant_product_tommy_1_1' + unit_price: 400 + tommy_order_made_by_john_item_1: + order: '@tommy_order_made_by_john' + variant: '@product_variant_product_tommy_1_1' + unit_price: 400 +BitBag\OpenMarketplace\Component\Order\Entity\Shipment: + bruce_order_made_by_john_1_shipment: + vendor: '@vendor_bruce' + order: '@bruce_order_made_by_john_1' + method: '@shipping_method_ups' + bruce_order_made_by_john_2_shipment: + vendor: '@vendor_bruce' + order: '@bruce_order_made_by_john_2' + method: '@shipping_method_fedex' + tommy_order_made_by_john_eu_shipment: + vendor: '@vendor_bruce' + order: '@tommy_order_made_by_john_eu' + method: '@shipping_method_fedex' + tommy_order_made_by_peter_shipment: + vendor: '@vendor_bruce' + order: '@tommy_order_made_by_peter' + method: '@shipping_method_fedex' + tommy_order_made_by_john_shipment: + vendor: '@vendor_bruce' + order: '@tommy_order_made_by_john' + method: '@shipping_method_fedex' + peter_order_made_by_john_shipment: + vendor: '@vendor_peter' + order: '@peter_order_made_by_john' + method: '@shipping_method_ups' +Sylius\Component\Core\Model\OrderItemUnit: + bruce_order_made_by_john_1_item_1_unit: + __construct: [ '@bruce_order_made_by_john_1_item_1' ] + shipment: '@bruce_order_made_by_john_1_shipment' + bruce_order_made_by_john_2_item_1_unit: + __construct: [ '@bruce_order_made_by_john_2_item_1' ] + shipment: '@bruce_order_made_by_john_2_shipment' + peter_order_made_by_john_1_item_1_unit: + __construct: [ '@peter_order_made_by_john_1_item_1' ] + shipment: '@peter_order_made_by_john_shipment' + tommy_order_made_by_john_eu_item_1_unit: + __construct: [ '@tommy_order_made_by_john_eu_item_1' ] + shipment: '@tommy_order_made_by_john_eu_shipment' + tommy_order_made_by_peter_item_1_unit: + __construct: [ '@tommy_order_made_by_peter_item_1' ] + shipment: '@tommy_order_made_by_john_eu_shipment' + tommy_order_made_by_john_item_1_unit: + __construct: [ '@tommy_order_made_by_john_item_1' ] + shipment: '@tommy_order_made_by_john_shipment' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementGenerateCommandTest/test_it_generates_settlements_for_incomplete_period.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementGenerateCommandTest/test_it_generates_settlements_for_incomplete_period.yaml new file mode 100644 index 0000000..f8555fa --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementGenerateCommandTest/test_it_generates_settlements_for_incomplete_period.yaml @@ -0,0 +1,236 @@ +Sylius\Component\Addressing\Model\Country: + country_pl: + code: 'PL' + country_us: + code: 'US' +Sylius\Component\Addressing\Model\Zone: + zone_us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_us: + code: 'US' + belongsTo: '@zone_us' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' + euro: + code: 'EUR' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel_us: + code: 'US' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true + channel_eu: + code: 'EU' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@euro' + enabled: true +Sylius\Component\Core\Model\ShippingMethod: + shipping_method_ups: + code: 'ups' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: [ '@channel_eu' ] + configuration: + CODE: + amount: 5 + shipping_method_fedex: + code: 'fedex' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: [ '@channel_eu' ] + configuration: + CODE: + amount: 5 +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' + customer_john: + firstName: 'John' + lastName: 'Smith' + email: 'john.smith@example.com' + emailCanonical: 'john.smith@example.com' + phoneNumber: 123456789 +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + usernameCanonical: 'bruce.wayne@example.com' + user_john: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_john' + username: 'john.smith@example.com' + usernameCanonical: 'john.smith@example.com' +Sylius\Component\Core\Model\Address: + address_john: + firstName: 'John' + lastName: 'Smith' + countryCode: 'US' + city: 'Arkham City' + postcode: '00000' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL31109024026812185484588836' + phoneNumber: '555123123' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + createdAt: '' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + product_bruce_1: + vendor: '@vendor_bruce' + code: 'bruce_1' + enabled: true + channels: [ '@channel_eu' ] +Sylius\Component\Core\Model\ProductVariant: + product_variant_product_bruce_1_1: + product: '@product_bruce_1' + code: 'bruce_1_1' + enabled: true + onHold: 2 + onHand: 3 + tracked: true + product_variant_product_bruce_1_2: + product: '@product_bruce_1' + code: 'bruce_1_2' + enabled: true + onHand: 1 + tracked: true +Sylius\Component\Core\Model\ChannelPricing: + pricing_product_variant_product_bruce_1_1_us: + price: 10 + originalPrice: 15 + minimumPrice: 0 + channelCode: 'US' + productVariant: '@product_variant_product_bruce_1_1' + pricing_product_variant_product_bruce_1_2_us: + price: 13 + originalPrice: 25 + minimumPrice: 10 + channelCode: 'US' + productVariant: '@product_variant_product_bruce_1_2' + pricing_product_variant_product_bruce_1_1_eu: + price: 9 + originalPrice: 14 + minimumPrice: 0 + channelCode: 'EU' + productVariant: '@product_variant_product_bruce_1_1' + pricing_product_variant_product_bruce_1_2_eu: + price: 12 + originalPrice: 24 + minimumPrice: 9 + channelCode: 'EU' + productVariant: '@product_variant_product_bruce_1_2' +BitBag\OpenMarketplace\Component\Order\Entity\Order: + bruce_order_made_by_john_1_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_1_main' + channel: '@channel_eu' + bruce_order_made_by_john_1: + primaryOrder: '@bruce_order_made_by_john_1_main' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_bruce' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_1' + shippingAddress: '@address_john' + billingAddress: '@address_john' + paid_at: '' + commission_total: 35 + channel: '@channel_eu' + bruce_order_made_by_john_2_main: + mode: 'primary' + currency_code: 'EUR' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_2_main' + channel: '@channel_eu' + bruce_order_made_by_john_2: + primaryOrder: '@bruce_order_made_by_john_2_main' + mode: 'secondary' + currency_code: 'EUR' + locale_code: 'en-US' + vendor: '@vendor_bruce' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_2' + paid_at: '' + commission_total: 70 + channel: '@channel_eu' +BitBag\OpenMarketplace\Component\Order\Entity\OrderItem: + bruce_order_made_by_john_1_item_1: + order: '@bruce_order_made_by_john_1' + variant: '@product_variant_product_bruce_1_1' + unit_price: 540 + bruce_order_made_by_john_2_item_1: + order: '@bruce_order_made_by_john_2' + variant: '@product_variant_product_bruce_1_2' + unit_price: 1002 +BitBag\OpenMarketplace\Component\Order\Entity\Shipment: + bruce_order_made_by_john_1_shipment: + vendor: '@vendor_bruce' + order: '@bruce_order_made_by_john_1' + method: '@shipping_method_ups' + bruce_order_made_by_john_2_shipment: + vendor: '@vendor_bruce' + order: '@bruce_order_made_by_john_2' + method: '@shipping_method_fedex' +Sylius\Component\Core\Model\OrderItemUnit: + bruce_order_made_by_john_1_item_1_unit: + __construct: [ '@bruce_order_made_by_john_1_item_1' ] + shipment: '@bruce_order_made_by_john_1_shipment' + bruce_order_made_by_john_2_item_1_unit: + __construct: [ '@bruce_order_made_by_john_2_item_1' ] + shipment: '@bruce_order_made_by_john_2_shipment' +BitBag\OpenMarketplace\Component\Settlement\Entity\Settlement: + vendor_bruce_settlement: + vendor: '@vendor_bruce' + total_amount: 1002 + total_commission_amount: 70 + start_date: '' + end_date: '' + channel: '@channel_eu' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementGenerateCommandTest/test_it_not_generates_settlements_for_if_settlement_already_exist.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementGenerateCommandTest/test_it_not_generates_settlements_for_if_settlement_already_exist.yaml new file mode 100644 index 0000000..99067a6 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementGenerateCommandTest/test_it_not_generates_settlements_for_if_settlement_already_exist.yaml @@ -0,0 +1,340 @@ +Sylius\Component\Addressing\Model\Country: + country_pl: + code: 'PL' + country_us: + code: 'US' +Sylius\Component\Addressing\Model\Zone: + zone_us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_us: + code: 'US' + belongsTo: '@zone_us' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' + euro: + code: 'EUR' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel_us: + code: 'US' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true + channel_eu: + code: 'EU' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@euro' + enabled: true +Sylius\Component\Core\Model\ShippingMethod: + shipping_method_ups: + code: 'ups' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: [ '@channel_us', '@channel_eu' ] + configuration: + CODE: + amount: 5 + shipping_method_fedex: + code: 'fedex' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: [ '@channel_us', '@channel_eu' ] + configuration: + CODE: + amount: 5 +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' + customer_peter: + firstName: 'Peter' + lastName: 'Weyland' + email: 'peter.weyland@example.com' + emailCanonical: 'peter.weyland@example.com' + customer_john: + firstName: 'John' + lastName: 'Smith' + email: 'john.smith@example.com' + emailCanonical: 'john.smith@example.com' + phoneNumber: 123456789 +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + usernameCanonical: 'bruce.wayne@example.com' + user_peter: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_peter' + username: 'peter.weyland@example.com' + usernameCanonical: 'peter.weyland@example.com' + user_john: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_john' + username: 'john.smith@example.com' + usernameCanonical: 'john.smith@example.com' +Sylius\Component\Core\Model\Address: + address_john: + firstName: 'John' + lastName: 'Smith' + countryCode: 'US' + city: 'Arkham City' + postcode: '00000' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL31109024026812185484588836' + phoneNumber: '555123123' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + createdAt: '' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL17109024022586255711928552' + phoneNumber: '555444333' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + product_bruce_1: + vendor: '@vendor_bruce' + code: 'bruce_1' + enabled: true + channels: [ '@channel_us', '@channel_eu' ] + product_peter_1: + vendor: '@vendor_peter' + code: 'peter_2' + enabled: true + channels: [ '@channel_us', '@channel_eu' ] +Sylius\Component\Core\Model\ProductVariant: + product_variant_product_bruce_1_1: + product: '@product_bruce_1' + code: 'bruce_1_1' + enabled: true + onHold: 2 + onHand: 3 + tracked: true + product_variant_product_bruce_1_2: + product: '@product_bruce_1' + code: 'bruce_1_2' + enabled: true + onHand: 1 + tracked: true + product_variant_product_peter_1_1: + product: '@product_peter_1' + code: 'peter_1_1' + enabled: true + onHand: 3 + tracked: true +Sylius\Component\Core\Model\ChannelPricing: + pricing_product_variant_product_bruce_1_1_us: + price: 10 + originalPrice: 15 + minimumPrice: 0 + channelCode: 'US' + productVariant: '@product_variant_product_bruce_1_1' + pricing_product_variant_product_bruce_1_2_us: + price: 13 + originalPrice: 25 + minimumPrice: 10 + channelCode: 'US' + productVariant: '@product_variant_product_bruce_1_2' + pricing_product_variant_product_peter_1_1_us: + price: 9 + originalPrice: 12 + minimumPrice: 5 + channelCode: 'US' + productVariant: '@product_variant_product_peter_1_1' + pricing_product_variant_product_bruce_1_1_eu: + price: 9 + originalPrice: 14 + minimumPrice: 0 + channelCode: 'EU' + productVariant: '@product_variant_product_bruce_1_1' + pricing_product_variant_product_bruce_1_2_eu: + price: 12 + originalPrice: 24 + minimumPrice: 9 + channelCode: 'EU' + productVariant: '@product_variant_product_bruce_1_2' + pricing_product_variant_product_peter_1_1_eu: + price: 8 + originalPrice: 11 + minimumPrice: 4 + channelCode: 'EU' + productVariant: '@product_variant_product_peter_1_1' +BitBag\OpenMarketplace\Component\Order\Entity\Order: + bruce_order_made_by_john_1_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_1_main' + channel: '@channel_us' + bruce_order_made_by_john_1: + primaryOrder: '@bruce_order_made_by_john_1_main' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_bruce' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_1' + shippingAddress: '@address_john' + billingAddress: '@address_john' + paid_at: '' + commission_total: 35 + channel: '@channel_us' + bruce_order_made_by_john_2_main: + mode: 'primary' + currency_code: 'EUR' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_2_main' + paid_at: '' + channel: '@channel_eu' + bruce_order_made_by_john_2: + primaryOrder: '@bruce_order_made_by_john_2_main' + mode: 'secondary' + currency_code: 'EUR' + locale_code: 'en-US' + vendor: '@vendor_bruce' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_2' + paid_at: '' + commission_total: 70 + channel: '@channel_eu' + peter_order_made_by_john_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'peter_order_made_by_john_main' + channel: '@channel_eu' + peter_order_made_by_john: + primaryOrder: '@peter_order_made_by_john' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_peter' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'peter_order_made_by_john' + paid_at: '' + commission_total: 100 + channel: '@channel_eu' + order_made_by_peter_main: + mode: 'primary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_peter' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'order_made_by_peter_main' + channel: '@channel_us' + order_made_by_peter: + primaryOrder: '@order_made_by_peter_main' + mode: 'secondary' + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_peter' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'order_made_by_peter' + paid_at: '' + commission_total: 10 + channel: '@channel_us' +BitBag\OpenMarketplace\Component\Order\Entity\OrderItem: + bruce_order_made_by_john_1_item_1: + order: '@bruce_order_made_by_john_1' + variant: '@product_variant_product_bruce_1_1' + unit_price: 540 + bruce_order_made_by_john_2_item_1: + order: '@bruce_order_made_by_john_2' + variant: '@product_variant_product_bruce_1_2' + unit_price: 1002 + peter_order_made_by_john_1_item_1: + order: '@peter_order_made_by_john' + variant: '@product_variant_product_peter_1_1' + unit_price: 700 +BitBag\OpenMarketplace\Component\Order\Entity\Shipment: + bruce_order_made_by_john_1_shipment: + vendor: '@vendor_bruce' + order: '@bruce_order_made_by_john_1' + method: '@shipping_method_ups' + bruce_order_made_by_john_2_shipment: + vendor: '@vendor_bruce' + order: '@bruce_order_made_by_john_2' + method: '@shipping_method_fedex' + peter_order_made_by_john_shipment: + vendor: '@vendor_peter' + order: '@peter_order_made_by_john' + method: '@shipping_method_ups' +Sylius\Component\Core\Model\OrderItemUnit: + bruce_order_made_by_john_1_item_1_unit: + __construct: [ '@bruce_order_made_by_john_1_item_1' ] + shipment: '@bruce_order_made_by_john_1_shipment' + bruce_order_made_by_john_2_item_1_unit: + __construct: [ '@bruce_order_made_by_john_2_item_1' ] + shipment: '@bruce_order_made_by_john_2_shipment' + peter_order_made_by_john_1_item_1_unit: + __construct: [ '@peter_order_made_by_john_1_item_1' ] + shipment: '@peter_order_made_by_john_shipment' +BitBag\OpenMarketplace\Component\Settlement\Entity\Settlement: + vendor_bruce_settlement: + vendor: '@vendor_bruce' + total_amount: 1002 + total_commission_amount: 70 + start_date: '' + end_date: '' + channel: '@channel_eu' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementGenerateCommandTest/test_it_throws_exception_if_period_resolver_for_settlement_frequency_does_not_exist.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementGenerateCommandTest/test_it_throws_exception_if_period_resolver_for_settlement_frequency_does_not_exist.yaml new file mode 100644 index 0000000..8735ea0 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementGenerateCommandTest/test_it_throws_exception_if_period_resolver_for_settlement_frequency_does_not_exist.yaml @@ -0,0 +1,87 @@ +Sylius\Component\Addressing\Model\Country: + country_pl: + code: 'PL' + country_us: + code: 'US' +Sylius\Component\Addressing\Model\Zone: + zone_us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_us: + code: 'US' + belongsTo: '@zone_us' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' + euro: + code: 'EUR' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel_us: + code: 'US' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true + channel_eu: + code: 'EU' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@euro' + enabled: true +Sylius\Component\Core\Model\ShippingMethod: + shipping_method_ups: + code: 'ups' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: [ '@channel_us', '@channel_eu' ] + configuration: + CODE: + amount: 5 + shipping_method_fedex: + code: 'fedex' + calculator: 'flat_rate' + zone: '@zone_us' + enabled: true + channels: [ '@channel_us', '@channel_eu' ] + configuration: + CODE: + amount: 5 +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + usernameCanonical: 'bruce.wayne@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL31109024026812185484588836' + phoneNumber: '555123123' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + createdAt: '' + settlement_frequency: 'daily' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementRepositoryTest/test_it_finds_all_available_periods.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementRepositoryTest/test_it_finds_all_available_periods.yaml new file mode 100644 index 0000000..cbf950e --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementRepositoryTest/test_it_finds_all_available_periods.yaml @@ -0,0 +1,107 @@ +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' + euro: + code: 'EUR' +Sylius\Component\Core\Model\Channel: + channel_us: + code: 'US' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true + channel_eu: + code: 'EU' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@euro' + enabled: true +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' + customer_tommy: + firstName: 'Tommy' + lastName: 'Doe' + email: 'tommy.doe@example.com' + emailCanonical: 'tommy.doe@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + user_tommy: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_tommy' + username: 'tommy.doe@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '555123123' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_tommy: + shopUser: '@user_tommy' + companyName: 'Tommy Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'NL41ABNA3195199319' + phoneNumber: '555123123' + slug: 'Tommy-Enterprises-Inc' + description: 'description' + commission: 15 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Settlement\Entity\Settlement: + vendor_bruce_settlement_1: + vendor: '@vendor_bruce' + total_amount: 10600 + total_commission_amount: 200 + start_date: '' + end_date: '' + channel: '@channel_us' + vendor_bruce_settlement_2: + vendor: '@vendor_bruce' + total_amount: 10000 + total_commission_amount: 100 + start_date: '' + end_date: '' + channel: '@channel_eu' + vendor_bruce_settlement_3: + vendor: '@vendor_bruce' + total_amount: 100500 + total_commission_amount: 1029 + start_date: '' + end_date: '' + channel: '@channel_us' + vendor_tommy_settlement_1: + vendor: '@vendor_tommy' + total_amount: 100500 + total_commission_amount: 1029 + start_date: '' + end_date: '' + channel: '@channel_eu' + vendor_tommy_settlement_2: + vendor: '@vendor_tommy' + total_amount: 500 + total_commission_amount: 10 + start_date: '' + end_date: '' + channel: '@channel_us' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementRepositoryTest/test_it_finds_all_settlements_by_vendor.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementRepositoryTest/test_it_finds_all_settlements_by_vendor.yaml new file mode 100644 index 0000000..cbf950e --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementRepositoryTest/test_it_finds_all_settlements_by_vendor.yaml @@ -0,0 +1,107 @@ +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' + euro: + code: 'EUR' +Sylius\Component\Core\Model\Channel: + channel_us: + code: 'US' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true + channel_eu: + code: 'EU' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@euro' + enabled: true +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' + customer_tommy: + firstName: 'Tommy' + lastName: 'Doe' + email: 'tommy.doe@example.com' + emailCanonical: 'tommy.doe@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + user_tommy: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_tommy' + username: 'tommy.doe@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '555123123' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_tommy: + shopUser: '@user_tommy' + companyName: 'Tommy Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'NL41ABNA3195199319' + phoneNumber: '555123123' + slug: 'Tommy-Enterprises-Inc' + description: 'description' + commission: 15 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Settlement\Entity\Settlement: + vendor_bruce_settlement_1: + vendor: '@vendor_bruce' + total_amount: 10600 + total_commission_amount: 200 + start_date: '' + end_date: '' + channel: '@channel_us' + vendor_bruce_settlement_2: + vendor: '@vendor_bruce' + total_amount: 10000 + total_commission_amount: 100 + start_date: '' + end_date: '' + channel: '@channel_eu' + vendor_bruce_settlement_3: + vendor: '@vendor_bruce' + total_amount: 100500 + total_commission_amount: 1029 + start_date: '' + end_date: '' + channel: '@channel_us' + vendor_tommy_settlement_1: + vendor: '@vendor_tommy' + total_amount: 100500 + total_commission_amount: 1029 + start_date: '' + end_date: '' + channel: '@channel_eu' + vendor_tommy_settlement_2: + vendor: '@vendor_tommy' + total_amount: 500 + total_commission_amount: 10 + start_date: '' + end_date: '' + channel: '@channel_us' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementRepositoryTest/test_it_finds_last_settlement_for_vendor.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementRepositoryTest/test_it_finds_last_settlement_for_vendor.yaml new file mode 100644 index 0000000..997bfc1 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/SettlementRepositoryTest/test_it_finds_last_settlement_for_vendor.yaml @@ -0,0 +1,104 @@ +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Core\Model\Channel: + channel_us: + code: 'US' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' + customer_tommy: + firstName: 'Tommy' + lastName: 'Doe' + email: 'tommy.doe@example.com' + emailCanonical: 'tommy.doe@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + user_tommy: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_tommy' + username: 'tommy.doe@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '555123123' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_tommy: + shopUser: '@user_tommy' + companyName: 'Tommy Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'NL41ABNA3195199319' + phoneNumber: '555123123' + slug: 'Tommy-Enterprises-Inc' + description: 'description' + commission: 15 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Settlement\Entity\Settlement: + vendor_bruce_settlement_1: + vendor: '@vendor_bruce' + total_amount: 10600 + total_commission_amount: 200 + start_date: '' + end_date: '' + channel: '@channel_us' + vendor_bruce_settlement_2: + vendor: '@vendor_bruce' + total_amount: 10000 + total_commission_amount: 100 + start_date: '' + end_date: '' + channel: '@channel_us' + vendor_bruce_settlement_3: + vendor: '@vendor_bruce' + total_amount: 100500 + total_commission_amount: 1029 + start_date: '' + end_date: '' + channel: '@channel_us' + vendor_tommy_settlement_1: + vendor: '@vendor_tommy' + total_amount: 100500 + total_commission_amount: 1029 + start_date: '' + end_date: '' + channel: '@channel_us' + vendor_tommy_settlement_2: + vendor: '@vendor_tommy' + total_amount: 500 + total_commission_amount: 10 + start_date: '' + end_date: '' + channel: '@channel_us' + vendor_tommy_settlement_3: + vendor: '@vendor_tommy' + total_amount: 1500 + total_commission_amount: 29 + start_date: '' + end_date: '' + channel: '@channel_us' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/TaxonRepositoryTest/test_it_finds_vendor_taxons.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/TaxonRepositoryTest/test_it_finds_vendor_taxons.yaml new file mode 100644 index 0000000..8a7fa75 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/TaxonRepositoryTest/test_it_finds_vendor_taxons.yaml @@ -0,0 +1,149 @@ +Sylius\Component\Addressing\Model\Country: + USA: + code: 'US' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel: + code: 'code' + name: 'name' + locales: + - '@locale' + default_locale: '@locale' + tax_calculation_strategy: 'order_items_based' + base_currency: '@dollar' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'test@example.com' + emailCanonical: 'test2@example.com' + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'test2@example.com' + emailCanonical: 'test@example.com' + customer_clark: + firstName: 'Clark' + lastName: 'Kent' + email: 'test3@example.com' + emailCanonical: 'test3@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + username: 'oliver@queen.com' + usernameCanonical: 'oliver@queen.com' + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce@wayne.com' + usernameCanonical: 'bruce@wayne.com' + user_clark: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_clark' + username: 'clark@kent.com' + usernameCanonical: 'clark@kent.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address: + country: '@USA' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@vendor_address' + slug: 'oliver-queen-company' + description: 'description' + commission: 10 + commissionType: 'net' +Sylius\Component\Taxonomy\Model\TaxonTranslation: + taxon_translation: + locale: 'en_US' + name: 'name' + slug: 'slug' + taxon2_translation: + locale: 'en_US' + name: 'name2' + slug: 'slug2' +Sylius\Component\Core\Model\Taxon: + taxon: + code: 'menu_category' + translations: + - '@taxon_translation' + enabled: true + taxon2: + code: 'menu_category_child' + translations: + - '@taxon2_translation' + enabled: true + parent: '@taxon' +Sylius\Component\Core\Model\ProductTranslation: + first_product_US_translation: + name: 'test_name1' + slug: 'test_slug1' + locale: 'en_US' + second_product_US_translation: + name: 'test_name2' + slug: 'test_slug2' + locale: 'en_US' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + first_product: + mainTaxon: '@taxon' + vendor: '@vendor_oliver' + code: 'code' + channels: + - '@channel' + translations: + - '@first_product_US_translation' + second_product: + mainTaxon: '@taxon' + vendor: '@vendor_oliver' + code: 'code2' + channels: + - '@channel' + translations: + - '@second_product_US_translation' + third_product_without_translation: + mainTaxon: '@taxon' + vendor: '@vendor_oliver' + code: 'code3' + channels: + - '@channel' +Sylius\Component\Core\Model\ProductTaxon: + firs_relation: + taxon: '@taxon' + product: '@first_product' + second_relation: + taxon: '@taxon' + product: '@second_product' +Sylius\Component\Core\Model\ProductVariant: + first_variant: + product: '@first_product' + code: 'code' +BitBag\OpenMarketplace\Component\Order\Entity\Order: + bruce_order_made_with_oliver: + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_oliver' + customer: '@customer_bruce' + clarks_order_made_with_random_vendor: + currency_code: 'USD' + locale_code: 'en-US' + customer: '@customer_clark' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorContextStrategy/CustomerFilterStrategyTest/customer_filter_strategy.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorContextStrategy/CustomerFilterStrategyTest/customer_filter_strategy.yaml new file mode 100644 index 0000000..6abcdab --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorContextStrategy/CustomerFilterStrategyTest/customer_filter_strategy.yaml @@ -0,0 +1,90 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' + customer_peter: + firstName: 'Peter' + lastName: 'Weyland' + email: 'peter.weyland@example.com' + emailCanonical: 'peter.weyland@example.com' + customer_john: + firstName: 'John' + lastName: 'Smith' + email: 'john.smith@example.com' + emailCanonical: 'john.smith@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + usernameCanonical: 'bruce.wayne@example.com' + user_peter: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_peter' + username: 'peter.weyland@example.com' + usernameCanonical: 'peter.weyland@example.com' + user_john: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_john' + username: 'john.smith@example.com' + usernameCanonical: 'john.smith@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '555123123' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '555444333' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Order\Entity\Order: + bruce_order_made_by_john_1: + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_bruce' + customer: '@customer_john' + paymentState: 'awaiting_payment' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_john_1' + bruce_order_made_by_peter: + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_bruce' + customer: '@customer_peter' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'bruce_order_made_by_peter' + peter_order_made_by_john: + currency_code: 'USD' + locale_code: 'en-US' + vendor: '@vendor_peter' + customer: '@customer_john' + paymentState: 'paid' + state: 'new' + checkoutState: 'completed' + tokenValue: 'peter_order_made_by_john' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorContextStrategy/ProductDraftFilterStrategyTest/product_draft_filter_strategy.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorContextStrategy/ProductDraftFilterStrategyTest/product_draft_filter_strategy.yaml new file mode 100644 index 0000000..818971a --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorContextStrategy/ProductDraftFilterStrategyTest/product_draft_filter_strategy.yaml @@ -0,0 +1,154 @@ +Sylius\Component\Addressing\Model\Country: + country_us: + code: 'US' +Sylius\Component\Addressing\Model\Zone: + zone_us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Addressing\Model\ZoneMember: + zone_member_us: + code: 'US' + belongsTo: '@zone_us' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel: + code: 'CODE' + name: 'name' + defaultLocale: '@locale' + locales: [ '@locale' ] + taxCalculationStrategy: 'order_items_based' + baseCurrency: '@dollar' + enabled: true +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' + customer_peter: + firstName: 'Peter' + lastName: 'Weyland' + email: 'peter.weyland@example.com' + emailCanonical: 'peter.weyland@example.com' + customer_john: + firstName: 'John' + lastName: 'Smith' + email: 'john.smith@example.com' + emailCanonical: 'john.smith@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + usernameCanonical: 'bruce.wayne@example.com' + user_peter: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_peter' + username: 'peter.weyland@example.com' + usernameCanonical: 'peter.weyland@example.com' + user_john: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_john' + username: 'john.smith@example.com' + usernameCanonical: 'john.smith@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address_bruce: + country: '@country_us' + city: 'Arkham City' + postalCode: '00000' + street: 'Avenue 2115' + vendor_address_peter: + country: '@country_us' + city: 'San Francisco' + postalCode: '94016' + street: 'Unknown 1' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '555123123' + vendorAddress: '@vendor_address_bruce' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '555444333' + vendorAddress: '@vendor_address_peter' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttribute: + attribute_bruce_1: + vendor: '@vendor_bruce' + code: 'attribute_bruce_1' + type: 'text' + storageType: 'text' + translatable: 'true' + attribute_bruce_2: + vendor: '@vendor_bruce' + code: 'attribute_bruce_2' + type: 'text' + storageType: 'text' + translatable: 'true' + attribute_peter_1: + vendor: '@vendor_peter' + code: 'attribute_peter_1' + type: 'text' + storageType: 'text' + translatable: 'true' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttributeTranslation: + attribute_bruce_1_translations_us: + translatable: '@attribute_bruce_1' + locale: 'en_US' + name: 'attribute_bruce_1_us' + attribute_bruce_2_translations_us: + translatable: '@attribute_bruce_2' + locale: 'en_US' + name: 'attribute_bruce_2_us' + attribute_peter_1_translations_us: + translatable: '@attribute_peter_1' + locale: 'en_US' + name: 'attribute_peter_1_us' +BitBag\OpenMarketplace\Component\ProductListing\Entity\Listing: + product_listing_bruce_1: + code: 'product_listing_bruce_1' + vendor: '@vendor_bruce' + product_listing_bruce_2: + code: 'product_listing_bruce_2' + vendor: '@vendor_bruce' + verificationStatus: 'verified' + product_listing_peter_1: + code: 'product_listing_peter_1' + vendor: '@vendor_peter' +BitBag\OpenMarketplace\Component\ProductListing\Entity\Draft: + product_draft_bruce_1: + code: 'product_draft_bruce_1' + productListing: '@product_listing_bruce_1' + product_draft_bruce_2: + code: 'product_draft_bruce_2' + productListing: '@product_listing_bruce_2' + product_draft_peter_1: + code: 'product_draft_peter_1' + productListing: '@product_listing_peter_1' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorContextStrategy/ProductVariantFilterStrategyTest/product_variant_filter_strategy.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorContextStrategy/ProductVariantFilterStrategyTest/product_variant_filter_strategy.yaml new file mode 100644 index 0000000..bdd7315 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorContextStrategy/ProductVariantFilterStrategyTest/product_variant_filter_strategy.yaml @@ -0,0 +1,107 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' + customer_peter: + firstName: 'Peter' + lastName: 'Weyland' + email: 'peter.weyland@example.com' + emailCanonical: 'peter.weyland@example.com' + customer_john: + firstName: 'John' + lastName: 'Smith' + email: 'john.smith@example.com' + emailCanonical: 'john.smith@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + usernameCanonical: 'bruce.wayne@example.com' + user_peter: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_peter' + username: 'peter.weyland@example.com' + usernameCanonical: 'peter.weyland@example.com' + user_john: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_john' + username: 'john.smith@example.com' + usernameCanonical: 'john.smith@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '555123123' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '555444333' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Product\Entity\Product: + product_bruce_1: + vendor: '@vendor_bruce' + code: 'bruce_1' + enabled: true + product_bruce_2: + vendor: '@vendor_bruce' + code: 'bruce_2' + enabled: true + product_peter_1: + vendor: '@vendor_peter' + code: 'peter_2' + enabled: true +Sylius\Component\Core\Model\ProductVariant: + product_variant_product_bruce_1_1: + product: '@product_bruce_1' + code: 'bruce_1_1' + enabled: true + onHold: 2 + onHand: 3 + tracked: true + product_variant_product_bruce_1_2: + product: '@product_bruce_1' + code: 'bruce_1_2' + enabled: true + onHand: 1 + tracked: true + product_variant_product_bruce_2_1: + product: '@product_bruce_2' + code: 'bruce_2_1' + enabled: true + onHand: 0 + tracked: false + product_variant_product_peter_1_1: + product: '@product_peter_1' + code: 'peter_1_1' + enabled: true + onHand: 3 + tracked: true + product_variant_product_peter_1_2: + product: '@product_peter_1' + code: 'peter_1_2' + enabled: true + onHand: 1 + tracked: true diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorContextStrategy/VendorFilterStrategyTest/vendor_filter_strategy.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorContextStrategy/VendorFilterStrategyTest/vendor_filter_strategy.yaml new file mode 100644 index 0000000..6cba024 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorContextStrategy/VendorFilterStrategyTest/vendor_filter_strategy.yaml @@ -0,0 +1,81 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'bruce.wayne@example.com' + emailCanonical: 'bruce.wayne@example.com' + customer_peter: + firstName: 'Peter' + lastName: 'Weyland' + email: 'peter.weyland@example.com' + emailCanonical: 'peter.weyland@example.com' + customer_john: + firstName: 'John' + lastName: 'Smith' + email: 'john.smith@example.com' + emailCanonical: 'john.smith@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce.wayne@example.com' + usernameCanonical: 'bruce.wayne@example.com' + user_peter: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_peter' + username: 'peter.weyland@example.com' + usernameCanonical: 'peter.weyland@example.com' + user_john: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_john' + username: 'john.smith@example.com' + usernameCanonical: 'john.smith@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '555123123' + slug: 'Wayne-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_peter: + shopUser: '@user_peter' + companyName: 'Weyland Corp' + taxIdentifier: '7654321' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '555444333' + slug: 'Weyland-Corp' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\ProductListing\Entity\DraftAttribute: + attribute_bruce_1: + vendor: '@vendor_bruce' + code: 'attribute_bruce_1' + type: 'text' + storageType: 'text' + translatable: 'true' + attribute_bruce_2: + vendor: '@vendor_bruce' + code: 'attribute_bruce_2' + type: 'text' + storageType: 'text' + translatable: 'true' + attribute_peter_1: + vendor: '@vendor_peter' + code: 'attribute_peter_1' + type: 'text' + storageType: 'text' + translatable: 'true' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorProfileUpdaterTest/test_it_creates_pending_data_row_from_data.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorProfileUpdaterTest/test_it_creates_pending_data_row_from_data.yaml new file mode 100644 index 0000000..c9e55d2 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorProfileUpdaterTest/test_it_creates_pending_data_row_from_data.yaml @@ -0,0 +1,35 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'test@example.com' + emailCanonical: 'test@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + username: 'oliver@queen.com' + usernameCanonical: 'oliver@queen.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@vendor_address' + slug: 'test-company-name' + description: 'description' + commission: 10 + commissionType: 'net' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorProfileUpdaterTest/test_it_doesnt_update_any_vendor_data_immediately.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorProfileUpdaterTest/test_it_doesnt_update_any_vendor_data_immediately.yaml new file mode 100644 index 0000000..2e31de8 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorProfileUpdaterTest/test_it_doesnt_update_any_vendor_data_immediately.yaml @@ -0,0 +1,35 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'test@example.com' + emailCanonical: 'test@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + username: 'oliver@queen.com' + usernameCanonical: 'oliver@queen.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@vendor_address' + description: 'description' + slug: 'test-slug' + commission: 10 + commissionType: 'net' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorProfileUpdaterTest/test_vendor_data_are_updated_and_removed_correctly.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorProfileUpdaterTest/test_vendor_data_are_updated_and_removed_correctly.yaml new file mode 100644 index 0000000..f135348 --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorProfileUpdaterTest/test_vendor_data_are_updated_and_removed_correctly.yaml @@ -0,0 +1,53 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' + USA: + code: 'US' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'test@example.com' + emailCanonical: 'test@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + username: 'oliver@queen.com' + usernameCanonical: 'oliver@queen.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@vendor_address' + slug: 'test-company-name' + description: 'description' + commission: 10 + commissionType: 'net' +BitBag\OpenMarketplace\Component\Vendor\Entity\ProfileUpdate\Address: + vendor_new_address: + country: '@USA' + city: 'Central City' + postalCode: '99-000' + street: 'Arrow Street' +BitBag\OpenMarketplace\Component\Vendor\Entity\ProfileUpdate\ProfileUpdate: + vendor_oliver_update: + vendor: '@vendor_oliver' + companyName: 'new company' + taxIdentifier: 'new number' + bankAccountNumber: 'new iban' + phoneNumber: '999999999' + vendorAddress: '@vendor_new_address' + description: 'updated description' + token: 'hardcoded' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorRepositoryTest/test_it_finds_correct_vendor.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorRepositoryTest/test_it_finds_correct_vendor.yaml new file mode 100644 index 0000000..71b367b --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorRepositoryTest/test_it_finds_correct_vendor.yaml @@ -0,0 +1,63 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'test@example.com' + emailCanonical: 'test2@example.com' + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'test2@example.com' + emailCanonical: 'test@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + username: 'oliver@queen.com' + usernameCanonical: 'oliver@queen.com' + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce@wayne.com' + usernameCanonical: 'bruce@wayne.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + oliver_vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' + bruce_vendor_address: + country: '@poland' + city: 'Poznan' + postalCode: '61-512' + street: 'Umultowska 54' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Queen company' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@oliver_vendor_address' + slug: 'oliver-queen-company' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Wayne enterprise' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@bruce_vendor_address' + slug: 'bruce-wayne-company' + description: 'description' + commission: 10 + commissionType: 'net' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorRepositoryTest/test_it_finds_vendors_by_settlement_frequency.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorRepositoryTest/test_it_finds_vendors_by_settlement_frequency.yaml new file mode 100644 index 0000000..913112c --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorRepositoryTest/test_it_finds_vendors_by_settlement_frequency.yaml @@ -0,0 +1,69 @@ +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'test1@example.com' + emailCanonical: 'test1@example.com' + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'test2@example.com' + emailCanonical: 'test2@example.com' + customer_clark: + firstName: 'Clark' + lastName: 'Kent' + email: 'test3@example.com' + emailCanonical: 'test3@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_oliver' + username: 'oliver@example.com' + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce@example.com' + user_clark: + plainPassword: '123password' + roles: [ 'ROLE_USER', 'ROLE_VENDOR' ] + enabled: 'true' + customer: '@customer_clark' + username: 'clark@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Oliver Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '555123123' + slug: 'Oliver-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + settlementFrequency: 'weekly' + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Bruce Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '555123123' + slug: 'Bruce-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + settlementFrequency: 'monthly' + vendor_clark: + shopUser: '@user_clark' + companyName: 'Clark Enterprises, Inc.' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '555123123' + slug: 'Clark-Enterprises-Inc' + description: 'description' + commission: 10 + commissionType: 'net' + settlementFrequency: 'weekly' diff --git a/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorShippingMethodRepositoryTest/test_it_finds_all_enabled_shipping_methods_for_vendor_and_channel.yaml b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorShippingMethodRepositoryTest/test_it_finds_all_enabled_shipping_methods_for_vendor_and_channel.yaml new file mode 100644 index 0000000..88ed85e --- /dev/null +++ b/OpenMarketplace/tests/Integration/DataFixtures/ORM/VendorShippingMethodRepositoryTest/test_it_finds_all_enabled_shipping_methods_for_vendor_and_channel.yaml @@ -0,0 +1,94 @@ +Sylius\Component\Addressing\Model\Country: + poland: + code: 'PL' +Sylius\Component\Currency\Model\Currency: + dollar: + code: 'USD' +Sylius\Component\Locale\Model\Locale: + locale: + createdAt: '' + code: 'en_US' +Sylius\Component\Core\Model\Channel: + channel: + code: 'code' + name: 'name' + default_locale: '@locale' + tax_calculation_strategy: 'order_items_based' + base_currency: '@dollar' +Sylius\Component\Core\Model\Customer: + customer_oliver: + firstName: 'John' + lastName: 'Nowak' + email: 'test@example.com' + emailCanonical: 'test2@example.com' + customer_bruce: + firstName: 'Bruce' + lastName: 'Wayne' + email: 'test2@example.com' + emailCanonical: 'test@example.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\ShopUser: + user_oliver: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_oliver' + username: 'oliver@queen.com' + usernameCanonical: 'oliver@queen.com' + user_bruce: + plainPassword: '123password' + roles: [ 'ROLE_USER' ] + enabled: 'true' + customer: '@customer_bruce' + username: 'bruce@wayne.com' + usernameCanonical: 'bruce@wayne.com' +BitBag\OpenMarketplace\Component\Vendor\Entity\Address: + oliver_vendor_address: + country: '@poland' + city: 'Warsaw' + postalCode: '00-999' + street: 'Avenue 2115' + bruce_vendor_address: + country: '@poland' + city: 'Poznan' + postalCode: '61-512' + street: 'Umultowska 54' +BitBag\OpenMarketplace\Component\Vendor\Entity\Vendor: + vendor_oliver: + shopUser: '@user_oliver' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@oliver_vendor_address' + slug: 'oliver-queen-company' + description: 'description' + commission: 10 + commissionType: 'net' + vendor_bruce: + shopUser: '@user_bruce' + companyName: 'Test company name' + taxIdentifier: '1234567' + bankAccountNumber: 'PL97109024021972765458596357' + phoneNumber: '333111222' + vendorAddress: '@bruce_vendor_address' + slug: 'bruce-wayne-company' + description: 'description' + commission: 10 + commissionType: 'net' +Sylius\Component\Addressing\Model\Zone: + us: + code: 'US' + name: 'United States of America' + type: 'country' + scope: 'all' +Sylius\Component\Core\Model\ShippingMethod: + shipping_method_ups: + code: 'ups' + calculator: 'flat_rate' + zone: '@us' +BitBag\OpenMarketplace\Component\Vendor\Entity\VendorShippingMethod: + vendor_shipping_method_ups: + vendor: '@vendor_oliver' + shippingMethod: '@shipping_method_ups' + channelCode: 'CODE' + diff --git a/OpenMarketplace/tests/Integration/IntegrationTestCase.php b/OpenMarketplace/tests/Integration/IntegrationTestCase.php new file mode 100644 index 0000000..509540e --- /dev/null +++ b/OpenMarketplace/tests/Integration/IntegrationTestCase.php @@ -0,0 +1,27 @@ +dataFixturesPath = __DIR__ . '/DataFixtures/ORM'; + $this->expectedResponsesPath = __DIR__ . '/Responses/Expected'; + } +} diff --git a/OpenMarketplace/tests/Integration/Operator/ProductDraftFilesOperatorTest.php b/OpenMarketplace/tests/Integration/Operator/ProductDraftFilesOperatorTest.php new file mode 100644 index 0000000..073c4d4 --- /dev/null +++ b/OpenMarketplace/tests/Integration/Operator/ProductDraftFilesOperatorTest.php @@ -0,0 +1,101 @@ +productFromDraftFactory = $this->getContainer()->get('bitbag.open_marketplace.component.product_listing.draft_converter.factory.simple_product'); + + $fileSystemMap = $this->getContainer()->get('knp_gaufrette.filesystem_map'); + + $fileAdapter = $fileSystemMap->get('sylius_image')->getAdapter(); + + $this->fileSystem = new Filesystem($fileAdapter); + + $productImageFactory = $this->getContainer()->get('bitbag.open_marketplace.component.product.factory.product_image'); + + $this->productDraftFilesOperator = new ImagesOperator($this->fileSystem, $productImageFactory); + } + + public function test_it_copies_draft_image_to_product(): void + { + $this->loadFixturesFromFile('ProductDraftFilesOperatorTest/test_it_copies_draft_images_to_product.yaml'); + + $manager = $this->getEntityManager(); + + $this->create_draft_fixture_with_file(); + + $draftFixture = $manager->getRepository(Draft::class)->findOneBy(['code' => 'FIXTURE']); + $cratedProduct = $this->productFromDraftFactory->create($draftFixture); + + $this->productDraftFilesOperator->copyFilesToProduct($draftFixture, $cratedProduct); + + $expectedFilePathKey = 'AA/test-new.png'; + + $manager->persist($cratedProduct); + $manager->flush(); + + $product = $manager->getRepository(Product::class)->findOneBy(['code' => 'FIXTURE' . '-' . $draftFixture->getProductListing()->getVendor()->getId()]); + + self::assertCount(1, $product->getImages()); + self::assertEquals($expectedFilePathKey, $product->getImages()[0]->getPath()); + } + + private function create_draft_fixture_with_file(): void + { + $manager = $this->getEntityManager(); + + $listing = $this->getEntityManager()->getRepository(Listing::class)->findAll()[0]; + + $image1 = new DraftImage(); + + $draftFixture = new Draft(); + $draftFixture->setCode('FIXTURE'); + $draftFixture->setProductListing($listing); + $draftFixture->addImage($image1); + $draftFixture->setIsVerified(false); + + $fileInfo = new \SplFileInfo(__DIR__ . '/test.png'); + $fileObject = $fileInfo->openFile('r'); + $file = $fileObject->fread(filesize(__DIR__ . '/test.png')); + + $originalFilePathName = 'AA/test.png'; + + if ($this->fileSystem->has('AA/test.png')) { + $this->fileSystem->delete('AA/test.png'); + } + + if ($this->fileSystem->has('AA/test1.png')) { + $this->fileSystem->delete('AA/test1.png'); + } + + $this->fileSystem->write('AA/test.png', $file); + + $image1->setPath('AA/test.png'); + $image1->setOwner($draftFixture); + + $manager->persist($draftFixture); + $manager->flush(); + } +} diff --git a/OpenMarketplace/tests/Integration/Operator/test.png b/OpenMarketplace/tests/Integration/Operator/test.png new file mode 100644 index 0000000..4897b96 Binary files /dev/null and b/OpenMarketplace/tests/Integration/Operator/test.png differ diff --git a/OpenMarketplace/tests/Integration/Repository/ChannelRepositoryTest.php b/OpenMarketplace/tests/Integration/Repository/ChannelRepositoryTest.php new file mode 100644 index 0000000..1ef53e8 --- /dev/null +++ b/OpenMarketplace/tests/Integration/Repository/ChannelRepositoryTest.php @@ -0,0 +1,40 @@ +entityManager = $this->getContainer()->get('doctrine.orm.entity_manager'); + $this->repository = $this->getContainer()->get('sylius.repository.channel'); + } + + public function test_it_finds_all_enabled_channels(): void + { + $this->loadFixturesFromFile('ChannelRepositoryTest/test_it_finds_all_enabled_channels.yaml'); + $result = $this->repository->findAllEnabled(); + + self::assertCount(2, $result); + } + + public function test_it_finds_enabled_channel_by_code(): void + { + $this->loadFixturesFromFile('ChannelRepositoryTest/test_it_finds_all_enabled_channels.yaml'); + $result = $this->repository->findOneEnabledByCode('US'); + + self::assertNotNull($result); + } +} diff --git a/OpenMarketplace/tests/Integration/Repository/ConversationRepositoryTest.php b/OpenMarketplace/tests/Integration/Repository/ConversationRepositoryTest.php new file mode 100644 index 0000000..6c53373 --- /dev/null +++ b/OpenMarketplace/tests/Integration/Repository/ConversationRepositoryTest.php @@ -0,0 +1,41 @@ +getContainer()->get('open_marketplace.repository.conversation'); + $this->loadFixturesFromFile('ConversationRepositoryTest/test_it_finds_all_conversations_with_status_and_user.yaml'); + + $userOliver = $this->getEntityManager()->getRepository(ShopUser::class)->findOneBy(['username' => 'oliver@queen.com']); + $userBruce = $this->getEntityManager()->getRepository(ShopUser::class)->findOneBy(['username' => 'oliver@queen.com']); + $statuses = [Conversation::STATUS_OPEN, Conversation::STATUS_CLOSED]; + foreach ($statuses as $status) { + $oliverConversations = $conversationRepository->findAllWithStatusAndUser($status, $userOliver); + $bruceConversations = $conversationRepository->findAllWithStatusAndUser($status, $userBruce); + + $this->assertEquals(count($oliverConversations), 1); + $this->assertEquals(count($bruceConversations), 1); + } + } +} diff --git a/OpenMarketplace/tests/Integration/Repository/CustomerRepositoryTest.php b/OpenMarketplace/tests/Integration/Repository/CustomerRepositoryTest.php new file mode 100644 index 0000000..b45fe62 --- /dev/null +++ b/OpenMarketplace/tests/Integration/Repository/CustomerRepositoryTest.php @@ -0,0 +1,48 @@ +entityManager = $this->getContainer()->get('doctrine.orm.entity_manager'); + $this->repository = $this->getContainer()->get('sylius.repository.customer'); + } + + public function test_it_finds_all_customers_of_vendor(): void + { + $this->loadFixturesFromFile('CustomerRepositoryTest/test_it_finds_all_customers_of_vendor.yaml'); + + $vendorOliver = $this->entityManager->getRepository(Vendor::class)->findOneBy(['slug' => 'oliver-queen-company']); + $queryBuilder = $this->repository->findVendorCustomers($vendorOliver); + + $result = $queryBuilder->getQuery()->getResult(); + self::assertCount(1, $result); + } + + public function test_it_finds_order_for_vendor(): void + { + $this->loadFixturesFromFile('CustomerRepositoryTest/test_it_finds_order_for_vendor.yaml'); + + $vendorOliver = $this->entityManager->getRepository(Vendor::class)->findOneBy(['slug' => 'oliver-queen-company']); + $customer = $this->entityManager->getRepository(Customer::class)->findOneBy(['email' => 'test2@example.com']); + $result = $this->repository->findCustomerForVendor($vendorOliver, (string) $customer->getId()); + + self::assertEquals($customer->getId(), $result->getId()); + } +} diff --git a/OpenMarketplace/tests/Integration/Repository/DraftAttributeRepositoryTest.php b/OpenMarketplace/tests/Integration/Repository/DraftAttributeRepositoryTest.php new file mode 100644 index 0000000..0cad90e --- /dev/null +++ b/OpenMarketplace/tests/Integration/Repository/DraftAttributeRepositoryTest.php @@ -0,0 +1,40 @@ +entityManager = $this->getContainer()->get('doctrine.orm.entity_manager'); + $this->repository = $this->entityManager->getRepository(DraftAttribute::class); + } + + public function test_it_finds_all_draft_attributes_for_given_vendor(): void + { + $this->loadFixturesFromFile('DraftAttributeRepositoryTest/test_it_finds_all_draft_attributes_for_given_vendor.yaml'); + + $vendorOliver = $this->getEntityManager()->getRepository(Vendor::class)->findOneBy(['slug' => 'oliver-queen-company']); + $vendorBruce = $this->getEntityManager()->getRepository(Vendor::class)->findOneBy(['slug' => 'bruce-wayne-company']); + + $oliversAttributes = $this->repository->findVendorDraftAttributes($vendorOliver); + $brucesAttributes = $this->repository->findVendorDraftAttributes($vendorBruce); + + self::assertCount(2, $oliversAttributes); + self::assertCount(1, $brucesAttributes); + } +} diff --git a/OpenMarketplace/tests/Integration/Repository/OrderRepositoryTest.php b/OpenMarketplace/tests/Integration/Repository/OrderRepositoryTest.php new file mode 100644 index 0000000..2dff52b --- /dev/null +++ b/OpenMarketplace/tests/Integration/Repository/OrderRepositoryTest.php @@ -0,0 +1,102 @@ +orderRepository = self::getContainer()->get('sylius.repository.order'); + $this->vendorRepository = self::getContainer()->get('bitbag.open_marketplace.component.vendor.repository.vendor'); + } + + public function test_it_finds_all_customers_of_vendor(): void + { + $this->loadFixturesFromFile('OrderRepositoryTest/test_it_finds_all_vendor_orders.yaml'); + + $vendorOliver = $this->vendorRepository->findOneBy(['slug' => 'oliver-queen-company']); + $queryBuilder = $this->orderRepository->findAllByVendorQueryBuilder($vendorOliver); + + $result = $queryBuilder->getQuery()->getResult(); + self::assertCount(1, $result); + } + + public function test_it_finds_order_for_vendor(): void + { + $this->loadFixturesFromFile('OrderRepositoryTest/test_it_finds_order_for_vendor.yaml'); + + $vendorOliver = $this->vendorRepository->findOneBy(['slug' => 'oliver-queen-company']); + $order = $this->orderRepository->findOneBy(['vendor' => $vendorOliver]); + $result = $this->orderRepository->findOrderForVendor($vendorOliver, (string) $order->getId()); + + self::assertEquals($order->getId(), $result->getId()); + } + + public function test_it_finds_orders_for_vendors_customer(): void + { + $this->loadFixturesFromFile('OrderRepositoryTest/test_it_finds_orders_for_vendors_customer.yaml'); + + $vendorOliver = $this->vendorRepository->findOneBy(['slug' => 'oliver-queen-company']); + $customer = self::getContainer()->get('sylius.repository.customer')->findOneBy(['email' => 'test2@example.com']); + $queryBuilder = $this->orderRepository->findOrdersForVendorByCustomer($vendorOliver, (string) $customer->getId()); + + $result = $queryBuilder->getQuery()->getResult(); + self::assertCount(1, $result); + } + + public function test_it_finds_for_settlement(): void + { + $this->loadFixturesFromFile('OrderRepositoryTest/test_it_finds_for_settlement.yaml'); + $vendorWayne = $this->vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + $vendorWeyland = $this->vendorRepository->findOneBy(['slug' => 'Weyland-Corp']); + $channel = self::getContainer()->get('sylius.repository.channel')->findOneBy(['code' => 'US']); + + $startDate = new \DateTime('last week monday 00:00:00'); + $endDate = new \DateTime('last week sunday 23:59:59'); + + $lastSettlementVendorWeyland = $this->orderRepository->findForSettlementByVendorAndChannelAndDates($vendorWeyland, $channel, $startDate, $endDate); + $lastSettlementVendorWayne = $this->orderRepository->findForSettlementByVendorAndChannelAndDates($vendorWayne, $channel, $startDate, $endDate); + + $this->assertSame($lastSettlementVendorWayne['total'], '1002'); + $this->assertSame($lastSettlementVendorWayne['commissionTotal'], '70'); + $this->assertNull($lastSettlementVendorWeyland['total']); + $this->assertNull($lastSettlementVendorWeyland['commissionTotal']); + } + + public function test_it_counts_order_for_settlement(): void + { + $this->loadFixturesFromFile('OrderRepositoryTest/test_it_counts_order_for_settlement.yaml'); + $settlementRepository = self::getContainer()->get('open_marketplace.repository.settlement'); + $settlements = $settlementRepository->findAll(); + $this->assertCount(1, $settlements); + $this->assertSame( + 2, + $this->orderRepository->countOrderForSettlement($settlements[0]) + ); + } + + public function test_it_create_query_builder_to_find_order_for_settlement(): void + { + $this->loadFixturesFromFile('OrderRepositoryTest/test_it_create_query_builder_to_find_order_for_settlement.yaml'); + $settlementRepository = self::getContainer()->get('open_marketplace.repository.settlement'); + $settlements = $settlementRepository->findAll(); + $this->assertCount(1, $settlements); + + $this->assertCount( + 2, + $this->orderRepository->findForSettlementQueryBuilder($settlements[0])->getQuery()->getResult() + ); + } +} diff --git a/OpenMarketplace/tests/Integration/Repository/ProductListingRepositoryTest.php b/OpenMarketplace/tests/Integration/Repository/ProductListingRepositoryTest.php new file mode 100644 index 0000000..b6fa5af --- /dev/null +++ b/OpenMarketplace/tests/Integration/Repository/ProductListingRepositoryTest.php @@ -0,0 +1,47 @@ +entityManager = $this->getContainer()->get('doctrine.orm.entity_manager'); + $this->repository = $this->entityManager->getRepository(Listing::class); + } + + public function test_it_finds_product_listings_with_latest_draft(): void + { + $this->loadFixturesFromFile('ProductListingRepositoryTest/test_it_finds_product_listings_with_latest_draft.yaml'); + + $queryBuilder = $this->repository->createQueryBuilderWithLatestDraft(); + + $result = $queryBuilder->getQuery()->getResult(); + self::assertCount(3, $result); + } + + public function test_it_finds_product_listings_with_latest_draft_by_vendor(): void + { + $this->loadFixturesFromFile('ProductListingRepositoryTest/test_it_finds_product_listings_with_latest_draft_by_vendor.yaml'); + + $vendorOliver = $this->entityManager->getRepository(Vendor::class)->findOneBy(['slug' => 'oliver-queen-company']); + $queryBuilder = $this->repository->createQueryBuilderByVendor($vendorOliver); + + $result = $queryBuilder->getQuery()->getResult(); + self::assertCount(2, $result); + } +} diff --git a/OpenMarketplace/tests/Integration/Repository/ProductRepositoryTest.php b/OpenMarketplace/tests/Integration/Repository/ProductRepositoryTest.php new file mode 100644 index 0000000..f1eeb07 --- /dev/null +++ b/OpenMarketplace/tests/Integration/Repository/ProductRepositoryTest.php @@ -0,0 +1,44 @@ +entityManager = $this->getContainer()->get('doctrine.orm.entity_manager'); + $this->repository = $this->entityManager->getRepository(Product::class); + $this->taxonProvider = $this->getContainer()->get('bitbag.open_marketplace.component.vendor.context.taxon'); + } + + public function test_it_finds_vendor_products(): void + { + $this->loadFixturesFromFile('ProductRepositoryTest/test_it_finds_vendor_products.yaml'); + /** @var VendorInterface $vendorOliver */ + $vendorOliver = $this->entityManager->getRepository(Vendor::class)->findOneBySlug('oliver-queen-company'); + $channel = $this->entityManager->getRepository(Channel::class)->findAll()[0]; + $localeCode = $channel->getDefaultLocale()->getCode(); + $taxon = $this->taxonProvider->getForVendorPage(null, $localeCode); + /** @var QueryBuilder $vendorProductsQuery */ + $vendorProductsQuery = $this->repository->createVendorShopListQueryBuilder($vendorOliver, $channel, $taxon, 'en_US', [], true); + + $this->assertCount(2, $vendorProductsQuery->getQuery()->getResult()); + } +} diff --git a/OpenMarketplace/tests/Integration/Repository/ProductReviewRepositoryTest.php b/OpenMarketplace/tests/Integration/Repository/ProductReviewRepositoryTest.php new file mode 100644 index 0000000..bec2af6 --- /dev/null +++ b/OpenMarketplace/tests/Integration/Repository/ProductReviewRepositoryTest.php @@ -0,0 +1,53 @@ +loadFixturesFromFile('ProductReviewRepositoryTest/found_product_reviews_for_vendor.yaml'); + + /** @var VendorRepositoryInterface $vendorRepository */ + $vendorRepository = $this->getEntityManager()->getRepository(Vendor::class); + $vendor = $vendorRepository->findOneBy(['slug' => 'adam-ondra-company']); + + /** @var ProductReviewRepositoryInterface $productReviewRepository */ + $productReviewRepository = $this->getEntityManager()->getRepository(ProductReview::class); + $queryBuilder = $productReviewRepository->createVendorReviewsQueryBuilder($vendor); + + $productReviews = $queryBuilder->getQuery()->getResult(); + self::assertCount(2, $productReviews); + } + + public function test_find_product_reviews_for_vendor_not_found(): void + { + $this->loadFixturesFromFile('ProductReviewRepositoryTest/not_found_product_reviews_for_vendor.yaml'); + + /** @var VendorRepositoryInterface $vendorRepository */ + $vendorRepository = $this->getEntityManager()->getRepository(Vendor::class); + $vendor = $vendorRepository->findOneBy(['slug' => 'alex-honnold-company']); + + /** @var ProductReviewRepositoryInterface $productReviewRepository */ + $productReviewRepository = $this->getEntityManager()->getRepository(ProductReview::class); + $queryBuilder = $productReviewRepository->createVendorReviewsQueryBuilder($vendor); + + $productReviews = $queryBuilder->getQuery()->getResult(); + self::assertEmpty($productReviews); + } +} diff --git a/OpenMarketplace/tests/Integration/Repository/SettlementRepositoryTest.php b/OpenMarketplace/tests/Integration/Repository/SettlementRepositoryTest.php new file mode 100644 index 0000000..57e9c8b --- /dev/null +++ b/OpenMarketplace/tests/Integration/Repository/SettlementRepositoryTest.php @@ -0,0 +1,76 @@ +repository = self::getContainer()->get('open_marketplace.repository.settlement'); + } + + public function test_it_finds_last_settlement_for_vendor(): void + { + $this->loadFixturesFromFile('SettlementRepositoryTest/test_it_finds_last_settlement_for_vendor.yaml'); + $vendorRepository = self::getContainer()->get('open_marketplace.repository.vendor'); + $channelRepository = self::getContainer()->get('sylius.repository.channel'); + $vendor = $vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + $channel = $channelRepository->findOneBy(['code' => 'US']); + + $settlement = $this->repository->findLastByVendorAndChannel($vendor, $channel); + + $this->assertSame(10000, $settlement->getTotalAmount()); + $this->assertSame(100, $settlement->getTotalCommissionAmount()); + } + + public function test_it_finds_all_available_periods(): void + { + $this->loadFixturesFromFile('SettlementRepositoryTest/test_it_finds_all_available_periods.yaml'); + + $period[] = $this->generatePeriod('last week monday', 'last week sunday'); + $period[] = $this->generatePeriod('first day of last month', 'last day of last month'); + $period[] = $this->generatePeriod('first day of January', 'last day of January'); + $period[] = $this->generatePeriod('first day of April', 'last day of June'); + + rsort($period); + + $this->assertSame( + $period, + $this->repository->findAllPeriods() + ); + } + + public function test_it_finds_all_settlements_by_vendor(): void + { + $this->loadFixturesFromFile('SettlementRepositoryTest/test_it_finds_all_settlements_by_vendor.yaml'); + $vendorRepository = self::getContainer()->get('open_marketplace.repository.vendor'); + $vendor = $vendorRepository->findOneBy(['slug' => 'Wayne-Enterprises-Inc']); + $settlements = $this->repository->findAllByVendorQueryBuilder($vendor)->getQuery()->getResult(); + $this->assertCount(3, $settlements); + + foreach ($settlements as $settlement) { + $this->assertSame($vendor, $settlement->getVendor()); + } + } + + private function generatePeriod(string $startDate, string $endDate): string + { + return sprintf( + '%s - %s', + (new \DateTime($startDate))->format('j/m/Y'), + (new \DateTime($endDate))->format('j/m/Y') + ); + } +} diff --git a/OpenMarketplace/tests/Integration/Repository/TaxonRepositoryTest.php b/OpenMarketplace/tests/Integration/Repository/TaxonRepositoryTest.php new file mode 100644 index 0000000..e21b790 --- /dev/null +++ b/OpenMarketplace/tests/Integration/Repository/TaxonRepositoryTest.php @@ -0,0 +1,42 @@ +entityManager = $this->getContainer()->get('doctrine.orm.entity_manager'); + $this->repository = $this->getContainer()->get('sylius.repository.taxon'); + } + + public function test_it_finds_vendor_products(): void + { + $this->loadFixturesFromFile('TaxonRepositoryTest/test_it_finds_vendor_taxons.yaml'); + + $taxon = $this->repository->findForVendorPage('slug', 'en_US'); + + $this->assertSame('slug', $taxon->getSlug()); + } + + public function test_it_finds_null_wuth_incorrect_slug(): void + { + $this->loadFixturesFromFile('TaxonRepositoryTest/test_it_finds_vendor_taxons.yaml'); + + $taxon = $this->repository->findForVendorPage('badSlug', 'en_US'); + + $this->assertNull($taxon); + } +} diff --git a/OpenMarketplace/tests/Integration/Repository/VendorRepositoryTest.php b/OpenMarketplace/tests/Integration/Repository/VendorRepositoryTest.php new file mode 100644 index 0000000..cc820ce --- /dev/null +++ b/OpenMarketplace/tests/Integration/Repository/VendorRepositoryTest.php @@ -0,0 +1,51 @@ +repository = self::getContainer()->get('bitbag.open_marketplace.component.vendor.repository.vendor'); + } + + public function test_it_finds_correct_vendor(): void + { + $this->loadFixturesFromFile('VendorRepositoryTest/test_it_finds_correct_vendor.yaml'); + $vendorOliver = $this->repository->findOneBySlug('oliver-queen-company'); + $vendorBruce = $this->repository->findOneBySlug('bruce-wayne-company'); + + $this->assertEquals('Queen company', $vendorOliver->getCompanyName()); + $this->assertEquals('Wayne enterprise', $vendorBruce->getCompanyName()); + } + + public function test_it_finds_null_for_null_slug_vendor(): void + { + $this->loadFixturesFromFile('VendorRepositoryTest/test_it_finds_correct_vendor.yaml'); + $vendorOliver = $this->repository->findOneBySlug('Not_in_db_slug'); + + $this->assertNull($vendorOliver); + } + + public function test_it_finds_vendors_by_settlement_frequency(): void + { + $this->loadFixturesFromFile('VendorRepositoryTest/test_it_finds_vendors_by_settlement_frequency.yaml'); + $vendors = $this->repository->findAllBySettlementFrequency('weekly'); + $this->assertCount(2, $vendors); + + $this->assertSame('Oliver-Enterprises-Inc', $vendors[0]->getSlug()); + $this->assertSame('Clark-Enterprises-Inc', $vendors[1]->getSlug()); + } +} diff --git a/OpenMarketplace/tests/Integration/Repository/VendorShippingMethodRepositoryTest.php b/OpenMarketplace/tests/Integration/Repository/VendorShippingMethodRepositoryTest.php new file mode 100644 index 0000000..70cbf30 --- /dev/null +++ b/OpenMarketplace/tests/Integration/Repository/VendorShippingMethodRepositoryTest.php @@ -0,0 +1,37 @@ +entityManager = $this->getContainer()->get('doctrine.orm.entity_manager'); + $this->repository = $this->getContainer()->get('open_marketplace.repository.vendor_shipping_method'); + } + + public function test_it_finds_all_enabled_shipping_methods_for_vendor_and_channel(): void + { + $this->loadFixturesFromFile('VendorShippingMethodRepositoryTest/test_it_finds_all_enabled_shipping_methods_for_vendor_and_channel.yaml'); + + $vendor = $this->entityManager->getRepository(Vendor::class)->findOneBy(['slug' => 'oliver-queen-company']); + $channel = $this->entityManager->getRepository(Channel::class)->findOneBy(['code' => 'code']); + $vendorShippingMethods = $this->repository->findEnabledForChannel($vendor, $channel); + + self::assertCount(1, $vendorShippingMethods); + } +} diff --git a/OpenMarketplace/tests/Integration/Updater/VendorProfileUpdaterTest.php b/OpenMarketplace/tests/Integration/Updater/VendorProfileUpdaterTest.php new file mode 100644 index 0000000..46e1a7b --- /dev/null +++ b/OpenMarketplace/tests/Integration/Updater/VendorProfileUpdaterTest.php @@ -0,0 +1,169 @@ +entityManager = static::$container->get('doctrine.orm.entity_manager'); + + $this->countryRepository = $this->entityManager->getRepository(Country::class); + $this->vendorRepository = $this->entityManager->getRepository(Vendor::class); + $this->vendorProfileUpdateRepository = $this->entityManager->getRepository(ProfileUpdate::class); + $this->vendorAddressFactory = static::$container->get('bitbag.open_marketplace.component.vendor.profile.factory.address'); + $this->vendorProfileFactory = static::$container->get('bitbag.open_marketplace.component.vendor.profile.factory.profile_factory'); + $this->vendorProfileUpdateImageFactoryInterface = static::$container->get('bitbag.open_marketplace.component.vendor.profile.factory.profile_logo_image_factory'); + $this->vendorProfileUpdateBackgroundImageFactoryInterface = static::$container->get('bitbag.open_marketplace.component.vendor.profile.factory.profile_background_image_factory'); + $this->imageUploader = static::$container->get('sylius.image_uploader'); + $this->vendorLogoOperator = static::$container->get('bitbag.open_marketplace.component.vendor.profile.logo_image_operator'); + $this->vendorBackgroundImageOperator = static::$container->get('bitbag.open_marketplace.component.vendor.profile.background_image_operator'); + + $remover = static::$container->get('bitbag.open_marketplace.component.vendor.profile.profile_update_remover'); + $vendorProfileFactory = static::$container->get('bitbag.open_marketplace.component.vendor.profile.factory.profile_update_factory'); + + $senderMock = $this->createMock(SenderInterface::class); + $this->vendorProfileUpdater = new ProfileUpdater( + $this->entityManager, + $senderMock, + $remover, + $vendorProfileFactory, + $this->vendorProfileUpdateImageFactoryInterface, + $this->vendorProfileUpdateBackgroundImageFactoryInterface, + $this->imageUploader, + $this->vendorLogoOperator, + $this->vendorBackgroundImageOperator + ); + } + + public function test_it_doesnt_update_any_vendor_data_immediately(): void + { + $this->loadFixturesFromFile('VendorProfileUpdaterTest/test_it_doesnt_update_any_vendor_data_immediately.yaml'); + + $vendorDataBeforeFormSubmit = $this->vendorRepository + ->findOneBy(['taxIdentifier' => '1234567']); + + $vendorFormData = $this->createFakeUpdateFormData(); + + $fakeImage = new LogoImage(); + $fakeImage->setPath('fakepath'); + $fakeBackgroundImage = new BackgroundImage(); + $fakeBackgroundImage->setPath('fakepath'); + + $this->vendorProfileUpdater + ->createPendingVendorProfileUpdate($vendorFormData, $vendorDataBeforeFormSubmit, $fakeImage, $fakeBackgroundImage); + + $pendingData = $this->vendorProfileUpdateRepository + ->findOneBy(['vendor' => $vendorDataBeforeFormSubmit]); + + $this->assertNotEquals($pendingData->getCompanyName(), $vendorDataBeforeFormSubmit->getCompanyName()); + } + + private function createFakeUpdateFormData(): ProfileInterface + { + $poland = $this->countryRepository + ->findOneBy(['code' => 'PL']); + + $address = $this->vendorAddressFactory + ->createAddress('Grand Street', 'Warsaw', '00-22', $poland); + + $vendorData = $this->vendorProfileFactory + ->createVendor('Grand Company', '221133', 'PL14109024029586826934815556', '0-33 221 333 111', 'description', $address); + + $vendorData->setSlug('test-slug'); + + $this->entityManager->persist($vendorData); + $this->entityManager->persist($address); + + return $vendorData; + } + + public function test_it_creates_pending_data_row_from_data(): void + { + $this->loadFixturesFromFile('VendorProfileUpdaterTest/test_it_creates_pending_data_row_from_data.yaml'); + + $vendorFormData = $this->createFakeUpdateFormData(); + $currentVendor = $this->vendorRepository + ->findOneBy(['taxIdentifier' => '1234567']); + + $fakeImage = new LogoImage(); + $fakeImage->setPath('fakepath'); + $fakeBackgroundImage = new BackgroundImage(); + $fakeBackgroundImage->setPath('fakepath'); + + $this->vendorProfileUpdater + ->createPendingVendorProfileUpdate($vendorFormData, $currentVendor, $fakeImage, $fakeBackgroundImage); + + $pendingData = $this->entityManager + ->getRepository(ProfileUpdate::class) + ->findOneBy(['vendor' => $currentVendor]); + + $this->assertEquals($vendorFormData->getCompanyName(), $pendingData->getCompanyName()); + } + + public function test_vendor_information_is_updated_and_removed_correctly(): void + { + $this->loadFixturesFromFile('VendorProfileUpdaterTest/test_vendor_data_are_updated_and_removed_correctly.yaml'); + + $currentVendor = $this->vendorRepository + ->findOneBy(['taxIdentifier' => '1234567']); + + $vendorId = $currentVendor->getId(); + + $pendingData = $this->vendorProfileUpdateRepository + ->findOneBy(['vendor' => $currentVendor]); + + $this->vendorProfileUpdater + ->updateVendorFromPendingData($pendingData); + + $updatedVendor = $this->vendorRepository + ->findOneBy(['taxIdentifier' => 'new number']); + + $pendingData = $this->vendorProfileUpdateRepository + ->findOneBy(['vendor' => $updatedVendor]); + + $this->assertEquals($vendorId, $updatedVendor->getId()); + $this->assertEquals('new company', $updatedVendor->getCompanyName()); + $this->assertEquals(null, $pendingData); + } +} diff --git a/OpenMarketplace/translations/flashes.en.yml b/OpenMarketplace/translations/flashes.en.yml new file mode 100644 index 0000000..24807a1 --- /dev/null +++ b/OpenMarketplace/translations/flashes.en.yml @@ -0,0 +1,27 @@ +vendor: + vendor_register: Thank you for filling the Vendor registration form. Your request now will be reviewed by our administrators + +open_marketplace: + ui: + shipping_method_updated: "Shipping methods updated" + enabled: "Product successfully enabled" + disabled: "Product successfully disabled" + restored: "Product successfully restored" + removed: "Product successfully removed" + vendor_updated: "Confirmation email has been sent" + vendor_disabled: "Vendor's account has been successfully disabled." + vendor_enabled: "Vendor's account has been successfully enabled." + vendor_verified: 'Vendor has been successfully verified.' + product_listing_sent_to_verification: 'Product listing sent to verification.' + product_listing_created: 'Product listing created.' + product_listing_saved_and_sent_to_verification: 'Product listing saved and sent to verification.' + product_listing_saved: 'Product listing saved.' + product_listing_accepted: 'Product listing accepted.' + product_listing_rejected: 'Product listing rejected.' + product_listing_send_to_verification: 'Product listing sent to verification.' + product_listing_removed : 'The product listing you are trying to reach has been deleted.' + archive_message_send: 'Message requesting archiving of conversation has been sent' + settlement_accepted: 'Settlement has been accepted successfully.' + not_enough_funds: 'Not enough funds in selected wallet.' + settlement_created: 'Settlement has been created successfully.' + not_enough_balance: 'Not enough funds in selected wallet.' diff --git a/OpenMarketplace/translations/messages.en.yml b/OpenMarketplace/translations/messages.en.yml new file mode 100644 index 0000000..46122ff --- /dev/null +++ b/OpenMarketplace/translations/messages.en.yml @@ -0,0 +1,239 @@ +open_marketplace: + ui: + yes: Yes + no: No + none: None + enabled_channels: Enabled Channels + shipping_details: Shipping details + is_shipping_required: Is shipping required? + shipping_category: Shipping category + conversation_categories: Message categories + restored: Product successfully restored + removed: Product successfully removed + remove: Remove + restore_visibility: Restore visibility + restore: Restore + new_product_draft: New Product Listing + edit_product_draft: Edit Product Listing + draft_attributes: Attributes + manage_product_listing_attributes: Manage product listings attributes + no_draft_attributes: No attributes set. + no_draft_taxons: No taxons set. + inventory: Inventory + manage_product_listing_stock: Manage your product listings stock + clients: Customers + order_list: Orders + summary_of_your_order: Summary of your order(s) + product_list: Product listings + admin: Admin + customer: Customer + details: Details + disable: Disable + disabled: Disabled + edit: Edit + edit_vendor: Edit vendor + enable: Enable + enabled: Enabled + id: ID + tax_id: Tax ID + vendor_dashboard: Vendor dashboard + vendor_profile: Profile + vendor: Vendor + become_a_vendor: Become a Vendor + product_listings: Product listings + product_listing: Product listing + create_product_listing: Create new product listing + edit_product_listing: Edit product listing + show_product_listing: Product listing details + create_draft_attribute: Create attribute + edit_draft_attribute: Edit attribute + edit_inventory: Edit stock + edit_product_review: Edit product review + marketplace: Marketplace + my_vendor_account: Profile + manage_your_vendor_information_and_preferences: Manage your vendor information and preferences + your_vendor_profile: Your vendor profile + edit_your_vendor_information: Edit your vendor information + publishedAt: Published at + status: Status + tax_identifier: Tax Identifier + bank_account_number: Bank account number + not_blank: This field cannot be empty + missing_translation: missing translation + company_name: Company name + shop_user: Shop user + country: Country + city: City + street: Street + phone_number: Phone number + company_address: Company Address + postal_code: Postal code + pending_update_message: Your profile has been edited. Please approve the changes by clicking on the link in the email sent to you. + vendors: Vendors + settlements: Settlements + manage_your_finances: Manage your finances + virtual_wallets: Virtual wallets + manage_your_wallets: Manage your wallets and money withdraws + virtual_wallet: Virtual wallet + profit_withdrawal_amount: Withdrawal amount + profit_withdrawal: Profit withdrawal + my_wallets: My wallets + virtual_wallet_balance: Wallet balance + create_settlement: Create settlement + balance: Balance + withdraw: Withdraw + withdraw_funds: Withdraw funds + logo: Logo + background: Background + review: Review + invalid_logo: Please upload a valid image (jpg/png/svg) + description: Description + shipping_methods: Shipping methods + manage_shipping_methods: Manage shipping methods accepted in your store + open: Open + closed: Closed + minimum: minimum + original: original + price: Price + product_rejected_intro: Corresponding item has been rejected + product_overview: Product overview + rejected_listing_msg: This product has been rejected + more: More + register: + new_vendors: New vendors + conversations: Messages + conversations_listing: + username: Username + admin_header: Messages + admin_subheader: Manage your messages + listing_header_open: Open threads + listing_header_closed: Closed threads + your_open_conversations: Manage your open threads + your_closed_conversations: Manage your closed threads + reading_closed_conversation: You're reading thread, which has been closed. + breadcrumb_header: Messages + no_open_conversations: You have no open threads + no_closed_conversations: You have no closed threads + users: Users + open_conversations: Open threads + closed_conversations: Closed threads + create_new_conversation: New thread + create_new_conversation_breadcrumb: New thread + create_new_conversation_header: New thread + conversation: + user_conversation: Thread with user + admin_conversation: Thread with administrator + no_subject: No subject + header: Message from administrator + with: Started by + your_response_header: "Your response:" + attachment: Attachment + archive_request_text_first_line: Administrator wants to archive this thread. + archive_request_text_second_line: Have you solved your issue? + yes: Yes + no: No + no_category: Message from administrator + form: + conversation_message: + file: File + submit: Submit + conversation: + category: Category + messages: Message + users: User + grid: + conversation: + applicant: Applicant + archive: Archive + menu: + conversations: Messages + conversation_categories: Message categories + product_reviews: Product reviews + product_reviews: Product reviews + manage_product_reviews: Manage your product reviews + new_conversation_category: New conversation category + edit_conversation_category: Edit conversation category + unverified: Unverified + vendor_address: Vendor address + vendor_details: Vendor details + vendor_commission: Vendor commission + show_product_listings: Show product listings + verified: Accepted + verify: Verify + new_vendor: New Vendor + manage_products: Manage product listings + name: Name + accept: Accept + reject: Reject + confirm: Are you sure? + code: Code + rejected: Rejected + created: Created + under_verification: Under verification + published_at: Published at + verified_at: Verified at + version: Version + actions: Actions + create_new_product: Create Product listing + save: Save + save_and_add: Save and Add + save_draft: Save draft + send_for_verification: Send for verification + vendor_under_verification: Your vendor account is under verification. + vendor_verification_accepted: Request to become a Vendor has been granted by the Administrator. + order_not_found: The order with id orderId has not been found + invalid_csrf: Invalid csrf token. + rejection_details: Rejection details + no_media_uploaded: No media uploaded. + your_account_has_been_disabled: Your vendor account has been disabled. Please contact administrators for more information. + view_orders: View your orders + footer_signature: BitBag OpenMarketplace - an open-source MVM based on Symfony & Sylius. + commission: Commission + commission_type: Commission Type + vendor_test_credentials: Vendor test credentials + username: Username + password: Password + tax_category: Tax category + settlement: Settlement + settlement_frequency: Settlement frequency + weekly: Weekly + monthly: Monthly + quarterly: Quarterly + period: Period + total_amount: Total amount + total_commission_amount: Commission + total_profit_amount: Settlement amount + currency_code: Currency code + settlement_status: + new: New + accepted: Accepted + settled: Settled + show_settlements: Show settlements + show_virtual_wallets: Show virtual wallets + created_at: Created at + updated_at: Updated at + channel: Channel + total_orders: Total orders + show_orders: Show orders + orders: Orders + manage_orders: Manage your orders + customers: Customers + manage_customers: Manage customers who ordered in your store + email: + settlements_created: + subject: Settlement created + greetings: Hey, a new settlement has been created. + info: Settlement details + link_placeholder: View settlements info in your admin panel + vendor_profile_update: Vendor profile update requested + request_profile_update_greeting: Hey, you asked to change your company details. + request_profile_update_info: For security purposes, we need to verify your decision. Click on the link below if you want to make a change or ignore this message. + postal_code: Postal code + id: ID + tax_id: Tax ID + vendors: Vendors + menu: + shop: + account: + vendor: + header: Vendor account diff --git a/OpenMarketplace/translations/validators.en.yml b/OpenMarketplace/translations/validators.en.yml new file mode 100644 index 0000000..614eabf --- /dev/null +++ b/OpenMarketplace/translations/validators.en.yml @@ -0,0 +1,26 @@ +validator: + message: + organization_name: Company Name + tax_identifier: Tax Identifier + not_blank: This field cannot be empty + minimum: 'Required length: {{ limit }} characters.' + maximum: This field cannot be longer than {{ limit }} + vendor_dashboard: Vendor Dashboard + maximum_file_size: The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + image_mime_type: The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + minimum_image_width: The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + minimum_image_height: The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + maximum_image_width: The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + maximum_image_height: The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + slug_invalid: This is not valid slug + code_vendor_unique: User cannot have multiple products with same code + vendor_already_exists: Vendor for current user already exists + positive_or_zero_commission: Commission value must be positive or zero + product_listing_unique_code: Product Listing with given code already exists + not_valid_iban: This is not a valid International Bank Account Number (IBAN). + not_valid_choice: Not a valid choice + product_listing_blank_description: Please enter product description. + + messaging: + message: + not_allowed_mime_types: The mime type of the file is not allowed ({{ type }}) diff --git a/OpenMarketplace/webpack.config.js b/OpenMarketplace/webpack.config.js new file mode 100644 index 0000000..1686a96 --- /dev/null +++ b/OpenMarketplace/webpack.config.js @@ -0,0 +1,56 @@ +const path = require('path'); +const Encore = require('@symfony/webpack-encore'); + +const [bitbagCmsShop, bitbagCmsAdmin] = require('./vendor/bitbag/cms-plugin/webpack.config.js'); +const [bitbagWishlistShop, bitbagWishlistAdmin] = require('./vendor/bitbag/wishlist-plugin/webpack.config.js'); + +const syliusBundles = path.resolve(__dirname, 'vendor/sylius/sylius/src/Sylius/Bundle/'); +const uiBundleScripts = path.resolve(syliusBundles, 'UiBundle/Resources/private/js/'); +const uiBundleResources = path.resolve(syliusBundles, 'UiBundle/Resources/private/'); + +// Shop config +Encore + .setOutputPath('public/build/shop/') + .setPublicPath('/build/shop') + .addEntry('shop-entry', './assets/shop/entry.js') + .disableSingleRuntimeChunk() + .cleanupOutputBeforeBuild() + .copyFiles({ + from: 'vendor/sylius/sylius/src/Sylius/Bundle/UiBundle/Resources/private/img', + to: '../../assets/shop/img/[path][name].[ext]', + includeSubdirectories: true, + pattern: /.*/, + }) + .enableSourceMaps(!Encore.isProduction()) + .enableVersioning(Encore.isProduction()) + .enableSassLoader(); + +const shopConfig = Encore.getWebpackConfig(); + +shopConfig.resolve.alias['sylius/ui'] = uiBundleScripts; +shopConfig.resolve.alias['sylius/ui-resources'] = uiBundleResources; +shopConfig.resolve.alias['sylius/bundle'] = syliusBundles; +shopConfig.name = 'shop'; + +Encore.reset(); + +// Admin config +Encore + .setOutputPath('public/build/admin/') + .setPublicPath('/build/admin') + .addEntry('admin-entry', './assets/admin/entry.js') + .disableSingleRuntimeChunk() + .cleanupOutputBeforeBuild() + .enableSourceMaps(!Encore.isProduction()) + .enableVersioning(Encore.isProduction()) + .enableSassLoader(); + +const adminConfig = Encore.getWebpackConfig(); + +adminConfig.resolve.alias['sylius/ui'] = uiBundleScripts; +adminConfig.resolve.alias['sylius/ui-resources'] = uiBundleResources; +adminConfig.resolve.alias['sylius/bundle'] = syliusBundles; +adminConfig.externals = Object.assign({}, adminConfig.externals, { window: 'window', document: 'document' }); +adminConfig.name = 'admin'; + +module.exports = [shopConfig, adminConfig, bitbagCmsShop, bitbagCmsAdmin, bitbagWishlistShop, bitbagWishlistAdmin]; diff --git a/OpenMarketplace/yarn.lock b/OpenMarketplace/yarn.lock new file mode 100644 index 0000000..50070ce --- /dev/null +++ b/OpenMarketplace/yarn.lock @@ -0,0 +1,7226 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/remapping@^2.1.0": + version "2.2.0" + resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== + dependencies: + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== + dependencies: + "@babel/highlight" "^7.18.6" + +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.18.8", "@babel/compat-data@^7.19.3": + version "7.19.3" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.3.tgz" + integrity sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw== + +"@babel/core@^7.7.0": + version "7.19.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.3.tgz#2519f62a51458f43b682d61583c3810e7dcee64c" + integrity sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.19.3" + "@babel/helper-compilation-targets" "^7.19.3" + "@babel/helper-module-transforms" "^7.19.0" + "@babel/helpers" "^7.19.0" + "@babel/parser" "^7.19.3" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.19.3" + "@babel/types" "^7.19.3" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + +"@babel/generator@^7.19.3": + version "7.19.3" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.19.3.tgz" + integrity sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ== + dependencies: + "@babel/types" "^7.19.3" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + +"@babel/helper-annotate-as-pure@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz" + integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz" + integrity sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.18.6" + "@babel/types" "^7.18.9" + +"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.19.0", "@babel/helper-compilation-targets@^7.19.3": + version "7.19.3" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz" + integrity sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg== + dependencies: + "@babel/compat-data" "^7.19.3" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.21.3" + semver "^6.3.0" + +"@babel/helper-create-class-features-plugin@^7.18.6": + version "7.19.0" + resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz" + integrity sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-split-export-declaration" "^7.18.6" + +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.19.0": + version "7.19.0" + resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz" + integrity sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + regexpu-core "^5.1.0" + +"@babel/helper-define-polyfill-provider@^0.3.3": + version "0.3.3" + resolved "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz" + integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww== + dependencies: + "@babel/helper-compilation-targets" "^7.17.7" + "@babel/helper-plugin-utils" "^7.16.7" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" + +"@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== + +"@babel/helper-explode-assignable-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz" + integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0": + version "7.19.0" + resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz" + integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== + dependencies: + "@babel/template" "^7.18.10" + "@babel/types" "^7.19.0" + +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-member-expression-to-functions@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz" + integrity sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg== + dependencies: + "@babel/types" "^7.18.9" + +"@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.19.0": + version "7.19.0" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz" + integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.18.6" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.19.0" + "@babel/types" "^7.19.0" + +"@babel/helper-optimise-call-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz" + integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.19.0" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz" + integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw== + +"@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz" + integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-wrap-function" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9": + version "7.19.1" + resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz" + integrity sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/traverse" "^7.19.1" + "@babel/types" "^7.19.0" + +"@babel/helper-simple-access@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz" + integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-skip-transparent-expression-wrappers@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz" + integrity sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw== + dependencies: + "@babel/types" "^7.18.9" + +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-string-parser@^7.18.10": + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz" + integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw== + +"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": + version "7.19.1" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== + +"@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + +"@babel/helper-wrap-function@^7.18.9": + version "7.19.0" + resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz" + integrity sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg== + dependencies: + "@babel/helper-function-name" "^7.19.0" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.19.0" + "@babel/types" "^7.19.0" + +"@babel/helpers@^7.19.0": + version "7.19.0" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz" + integrity sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg== + dependencies: + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.19.0" + "@babel/types" "^7.19.0" + +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.18.10", "@babel/parser@^7.19.3": + version "7.19.3" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.19.3.tgz" + integrity sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ== + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz" + integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz" + integrity sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/plugin-proposal-optional-chaining" "^7.18.9" + +"@babel/plugin-proposal-async-generator-functions@^7.19.1": + version "7.19.1" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz" + integrity sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-remap-async-to-generator" "^7.18.9" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-proposal-class-properties@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz" + integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-proposal-class-static-block@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz" + integrity sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-proposal-dynamic-import@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz" + integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-proposal-export-namespace-from@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz" + integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-proposal-json-strings@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz" + integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-proposal-logical-assignment-operators@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz" + integrity sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz" + integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-proposal-numeric-separator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz" + integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz" + integrity sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q== + dependencies: + "@babel/compat-data" "^7.18.8" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.18.8" + +"@babel/plugin-proposal-optional-catch-binding@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz" + integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-proposal-optional-chaining@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz" + integrity sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-proposal-private-methods@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz" + integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-proposal-private-property-in-object@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz" + integrity sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-proposal-unicode-property-regex@^7.18.6", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz" + integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-dynamic-import@^7.0.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-import-assertions@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz" + integrity sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.14.5": + version "7.14.5" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-arrow-functions@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz" + integrity sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-async-to-generator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz" + integrity sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag== + dependencies: + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-remap-async-to-generator" "^7.18.6" + +"@babel/plugin-transform-block-scoped-functions@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz" + integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-block-scoping@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz" + integrity sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-classes@^7.19.0": + version "7.19.0" + resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz" + integrity sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-compilation-targets" "^7.19.0" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-split-export-declaration" "^7.18.6" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz" + integrity sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-destructuring@^7.18.13": + version "7.18.13" + resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz" + integrity sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz" + integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-duplicate-keys@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz" + integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-exponentiation-operator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz" + integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-for-of@^7.18.8": + version "7.18.8" + resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz" + integrity sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-function-name@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz" + integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== + dependencies: + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-literals@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz" + integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-member-expression-literals@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz" + integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-modules-amd@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz" + integrity sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg== + dependencies: + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-commonjs@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz" + integrity sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q== + dependencies: + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-systemjs@^7.19.0": + version "7.19.0" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz" + integrity sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A== + dependencies: + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-module-transforms" "^7.19.0" + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-validator-identifier" "^7.18.6" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-umd@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz" + integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ== + dependencies: + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.19.1": + version "7.19.1" + resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz" + integrity sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.19.0" + "@babel/helper-plugin-utils" "^7.19.0" + +"@babel/plugin-transform-new-target@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz" + integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-object-super@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz" + integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-replace-supers" "^7.18.6" + +"@babel/plugin-transform-parameters@^7.18.8": + version "7.18.8" + resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz" + integrity sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-property-literals@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz" + integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-regenerator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz" + integrity sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + regenerator-transform "^0.15.0" + +"@babel/plugin-transform-reserved-words@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz" + integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-shorthand-properties@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz" + integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-spread@^7.19.0": + version "7.19.0" + resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz" + integrity sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w== + dependencies: + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + +"@babel/plugin-transform-sticky-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz" + integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-template-literals@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz" + integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-typeof-symbol@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz" + integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-unicode-escapes@^7.18.10": + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz" + integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-unicode-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz" + integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/preset-env@^7.10.0": + version "7.19.3" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.19.3.tgz#52cd19abaecb3f176a4ff9cc5e15b7bf06bec754" + integrity sha512-ziye1OTc9dGFOAXSWKUqQblYHNlBOaDl8wzqf2iKXJAltYiR3hKHUKmkt+S9PppW7RQpq4fFCrwwpIDj/f5P4w== + dependencies: + "@babel/compat-data" "^7.19.3" + "@babel/helper-compilation-targets" "^7.19.3" + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9" + "@babel/plugin-proposal-async-generator-functions" "^7.19.1" + "@babel/plugin-proposal-class-properties" "^7.18.6" + "@babel/plugin-proposal-class-static-block" "^7.18.6" + "@babel/plugin-proposal-dynamic-import" "^7.18.6" + "@babel/plugin-proposal-export-namespace-from" "^7.18.9" + "@babel/plugin-proposal-json-strings" "^7.18.6" + "@babel/plugin-proposal-logical-assignment-operators" "^7.18.9" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" + "@babel/plugin-proposal-numeric-separator" "^7.18.6" + "@babel/plugin-proposal-object-rest-spread" "^7.18.9" + "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" + "@babel/plugin-proposal-optional-chaining" "^7.18.9" + "@babel/plugin-proposal-private-methods" "^7.18.6" + "@babel/plugin-proposal-private-property-in-object" "^7.18.6" + "@babel/plugin-proposal-unicode-property-regex" "^7.18.6" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-import-assertions" "^7.18.6" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-transform-arrow-functions" "^7.18.6" + "@babel/plugin-transform-async-to-generator" "^7.18.6" + "@babel/plugin-transform-block-scoped-functions" "^7.18.6" + "@babel/plugin-transform-block-scoping" "^7.18.9" + "@babel/plugin-transform-classes" "^7.19.0" + "@babel/plugin-transform-computed-properties" "^7.18.9" + "@babel/plugin-transform-destructuring" "^7.18.13" + "@babel/plugin-transform-dotall-regex" "^7.18.6" + "@babel/plugin-transform-duplicate-keys" "^7.18.9" + "@babel/plugin-transform-exponentiation-operator" "^7.18.6" + "@babel/plugin-transform-for-of" "^7.18.8" + "@babel/plugin-transform-function-name" "^7.18.9" + "@babel/plugin-transform-literals" "^7.18.9" + "@babel/plugin-transform-member-expression-literals" "^7.18.6" + "@babel/plugin-transform-modules-amd" "^7.18.6" + "@babel/plugin-transform-modules-commonjs" "^7.18.6" + "@babel/plugin-transform-modules-systemjs" "^7.19.0" + "@babel/plugin-transform-modules-umd" "^7.18.6" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.19.1" + "@babel/plugin-transform-new-target" "^7.18.6" + "@babel/plugin-transform-object-super" "^7.18.6" + "@babel/plugin-transform-parameters" "^7.18.8" + "@babel/plugin-transform-property-literals" "^7.18.6" + "@babel/plugin-transform-regenerator" "^7.18.6" + "@babel/plugin-transform-reserved-words" "^7.18.6" + "@babel/plugin-transform-shorthand-properties" "^7.18.6" + "@babel/plugin-transform-spread" "^7.19.0" + "@babel/plugin-transform-sticky-regex" "^7.18.6" + "@babel/plugin-transform-template-literals" "^7.18.9" + "@babel/plugin-transform-typeof-symbol" "^7.18.9" + "@babel/plugin-transform-unicode-escapes" "^7.18.10" + "@babel/plugin-transform-unicode-regex" "^7.18.6" + "@babel/preset-modules" "^0.1.5" + "@babel/types" "^7.19.3" + babel-plugin-polyfill-corejs2 "^0.3.3" + babel-plugin-polyfill-corejs3 "^0.6.0" + babel-plugin-polyfill-regenerator "^0.4.1" + core-js-compat "^3.25.1" + semver "^6.3.0" + +"@babel/preset-modules@^0.1.5": + version "0.1.5" + resolved "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz" + integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/runtime@^7.8.4": + version "7.19.0" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz" + integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.18.10": + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz" + integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.10" + "@babel/types" "^7.18.10" + +"@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.19.3": + version "7.19.3" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.3.tgz" + integrity sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.19.3" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.19.3" + "@babel/types" "^7.19.3" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.19.3", "@babel/types@^7.4.4": + version "7.19.3" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.19.3.tgz" + integrity sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw== + dependencies: + "@babel/helper-string-parser" "^7.18.10" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + +"@discoveryjs/json-ext@^0.5.0": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + +"@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" + integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.15" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz" + integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" + integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== + +"@nuxt/friendly-errors-webpack-plugin@^2.5.1": + version "2.5.2" + resolved "https://registry.yarnpkg.com/@nuxt/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-2.5.2.tgz#982a43ee2da61611f7396439e57038392d3944d5" + integrity sha512-LLc+90lnxVbpKkMqk5z1EWpXoODhc6gRkqqXJCInJwF5xabHAE7biFvbULfvTRmtaTzAaP8IV4HQDLUgeAUTTw== + dependencies: + chalk "^2.3.2" + consola "^2.6.0" + error-stack-parser "^2.0.0" + string-width "^4.2.3" + +"@symfony/webpack-encore@^1.7.0": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@symfony/webpack-encore/-/webpack-encore-1.8.2.tgz#ceffa0d9326d29fa62b3a61f213e8e01a9992a7e" + integrity sha512-ZOsOqaZNP3BSQuISAsyH/Jv5+rDxbM4Wf6IsKo1y5Cm9BFIS2dPLsqDZfMbi6G2HdAHm88JqX/HGwxE73eADEw== + dependencies: + "@babel/core" "^7.7.0" + "@babel/plugin-syntax-dynamic-import" "^7.0.0" + "@babel/preset-env" "^7.10.0" + "@nuxt/friendly-errors-webpack-plugin" "^2.5.1" + assets-webpack-plugin "7.0.*" + babel-loader "^8.2.2" + chalk "^4.0.0" + clean-webpack-plugin "^3.0.0" + css-loader "^5.2.4" + css-minimizer-webpack-plugin "^2.0.0" + fast-levenshtein "^3.0.0" + loader-utils "^2.0.0" + mini-css-extract-plugin "^1.5.0" + pkg-up "^3.1.0" + pretty-error "^3.0.3" + resolve-url-loader "^3.1.2" + semver "^7.3.2" + style-loader "^2.0.0" + sync-rpc "^1.3.6" + terser-webpack-plugin "^5.1.1" + tmp "^0.2.1" + webpack "^5.35" + webpack-cli "^4.9.1" + webpack-dev-server "^4.0.0" + yargs-parser "^20.2.4" + +"@trysound/sax@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.10" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" + integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== + dependencies: + "@types/node" "*" + +"@types/connect-history-api-fallback@^1.3.5": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" + integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/eslint-scope@^3.7.3": + version "3.7.4" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" + integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.4.6" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.6.tgz#7976f054c1bccfcf514bff0564c0c41df5c08207" + integrity sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" + integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== + +"@types/estree@^0.0.51": + version "0.0.51" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": + version "4.17.31" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz#a1139efeab4e7323834bb0226e62ac019f474b2f" + integrity sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.14" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.14.tgz#143ea0557249bc1b3b54f15db4c81c3d4eb3569c" + integrity sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/glob@^7.1.1": + version "7.2.0" + resolved "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/http-proxy@^1.17.8": + version "1.17.9" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.9.tgz#7f0e7931343761efde1e2bf48c40f02f3f75705a" + integrity sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw== + dependencies: + "@types/node" "*" + +"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.11" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + +"@types/mime@*": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" + integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== + +"@types/minimatch@*": + version "5.1.2" + resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz" + integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== + +"@types/node@*": + version "18.7.23" + resolved "https://registry.npmjs.org/@types/node/-/node-18.7.23.tgz" + integrity sha512-DWNcCHolDq0ZKGizjx2DZjR/PqsYwAcYUJmfMWqtVU2MBMG5Mo+xFZrhGId5r/O5HOuMPyQEcM6KUBp5lBZZBg== + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/retry@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== + +"@types/serve-index@^1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" + integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== + dependencies: + "@types/express" "*" + +"@types/serve-static@*", "@types/serve-static@^1.13.10": + version "1.15.0" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155" + integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg== + dependencies: + "@types/mime" "*" + "@types/node" "*" + +"@types/sockjs@^0.3.33": + version "0.3.33" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" + integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== + dependencies: + "@types/node" "*" + +"@types/source-list-map@*": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" + integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== + +"@types/tapable@^1": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.8.tgz#b94a4391c85666c7b73299fd3ad79d4faa435310" + integrity sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ== + +"@types/uglify-js@*": + version "3.17.0" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.17.0.tgz#95271e7abe0bf7094c60284f76ee43232aef43b9" + integrity sha512-3HO6rm0y+/cqvOyA8xcYLweF0TKXlAxmQASjbOi49Co51A1N4nR4bEwBgRoD9kNM+rqFGArjKr654SLp2CoGmQ== + dependencies: + source-map "^0.6.1" + +"@types/webpack-sources@*": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-3.2.0.tgz#16d759ba096c289034b26553d2df1bf45248d38b" + integrity sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg== + dependencies: + "@types/node" "*" + "@types/source-list-map" "*" + source-map "^0.7.3" + +"@types/webpack@^4.4.31": + version "4.41.32" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.32.tgz#a7bab03b72904070162b2f169415492209e94212" + integrity sha512-cb+0ioil/7oz5//7tZUSwbrSAN/NWHrQylz5cW8G0dWTcF/g+/dSdMlKVZspBYuMAN1+WnwHrkxiRrLcwd0Heg== + dependencies: + "@types/node" "*" + "@types/tapable" "^1" + "@types/uglify-js" "*" + "@types/webpack-sources" "*" + anymatch "^3.0.0" + source-map "^0.6.0" + +"@types/ws@^8.5.1": + version "8.5.3" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== + dependencies: + "@types/node" "*" + +"@webassemblyjs/ast@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" + integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + +"@webassemblyjs/floating-point-hex-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" + integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== + +"@webassemblyjs/helper-api-error@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" + integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== + +"@webassemblyjs/helper-buffer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" + integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== + +"@webassemblyjs/helper-numbers@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" + integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" + integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== + +"@webassemblyjs/helper-wasm-section@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" + integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + +"@webassemblyjs/ieee754@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" + integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" + integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" + integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== + +"@webassemblyjs/wasm-edit@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" + integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-wasm-section" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-opt" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wast-printer" "1.11.1" + +"@webassemblyjs/wasm-gen@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" + integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wasm-opt@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" + integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + +"@webassemblyjs/wasm-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" + integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wast-printer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" + integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webpack-cli/configtest@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5" + integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== + +"@webpack-cli/info@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1" + integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== + dependencies: + envinfo "^7.7.3" + +"@webpack-cli/serve@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" + integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abbrev@1: + version "1.1.1" + resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-es7-plugin@^1.1.7: + version "1.1.7" + resolved "https://registry.npmjs.org/acorn-es7-plugin/-/acorn-es7-plugin-1.1.7.tgz" + integrity sha512-7D+8kscFMf6F2t+8ZRYmv82CncDZETsaZ4dEl5lh3qQez7FVABk2Vz616SAbnIq1PbNsLVaZjl2oSkk5BWAKng== + +acorn-import-assertions@^1.7.6: + version "1.8.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" + integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz" + integrity sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ== + dependencies: + acorn "^3.0.4" + +"acorn@>= 2.5.2 <= 5.7.5": + version "4.0.13" + resolved "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz" + integrity sha512-fu2ygVGuMmlzG8ZeRJ0bvR41nsAkxxhbyk8bZ1SS521Z7vmgJFTQQlfz/Mp/nJexGBz+v8sC9bM6+lNgskt4Ug== + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz" + integrity sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw== + +acorn@^5.5.0: + version "5.7.4" + resolved "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz" + integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== + +acorn@^8.5.0, acorn@^8.7.1: + version "8.8.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + +adjust-sourcemap-loader@3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz" + integrity sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw== + dependencies: + loader-utils "^2.0.0" + regex-parser "^2.2.11" + +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^2.1.0: + version "2.1.1" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz" + integrity sha512-ZFztHzVRdGLAzJmpUT9LNFLe1YiVOEylcaNpEutM26PVTCtOD919IMfD01CgbRouB42Dd9atjx1HseC15DgOZA== + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@^5.2.3, ajv@^5.3.0: + version "5.5.2" + resolved "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz" + integrity sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw== + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + 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@^8.0.0, ajv@^8.8.0: + version "8.11.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" + integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz" + integrity sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg== + +ansi-escapes@^3.0.0: + version "3.2.0" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== + +ansi-regex@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz" + integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== + +ansi-regex@^4.1.0: + version "4.1.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz" + integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz" + integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA== + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + 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== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@^3.0.0, anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.7" + resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz" + integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arity-n@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz" + integrity sha512-fExL2kFDC1Q2DUOx3whE/9KoN66IzkY4b4zUHUBFM1ojEYjZZYDcUW3bek/ufGionX9giIKDC5redH2IlGqcQQ== + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz" + integrity sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw== + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +array-flatten@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-includes@^3.1.4: + version "3.1.5" + resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz" + integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + get-intrinsic "^1.1.1" + is-string "^1.0.7" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz" + integrity sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng== + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz" + integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== + +array.prototype.flat@^1.2.5: + version "1.3.0" + resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz" + integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.2" + es-shim-unscopables "^1.0.0" + +asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + +assets-webpack-plugin@7.0.*: + version "7.0.0" + resolved "https://registry.yarnpkg.com/assets-webpack-plugin/-/assets-webpack-plugin-7.0.0.tgz#c61ed7466f35ff7a4d90d7070948736f471b8804" + integrity sha512-DMZ9r6HFxynWeONRMhSOFTvTrmit5dovdoUKdJgCG03M6CC7XiwNImPH+Ad1jaVrQ2n59e05lBhte52xPt4MSA== + dependencies: + camelcase "^6.0.0" + escape-string-regexp "^4.0.0" + lodash "^4.17.20" + +async-foreach@^0.1.3: + version "0.1.3" + resolved "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz" + integrity sha512-VUeSMD8nEGBWaZK4lizI1sf3yEC7pnAQ/mrI7pC2fBz2s/tq5jWWEngTwaf0Gruu/OoXRGLGg1XFqpYBiGTYJA== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz" + integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== + +aws4@^1.8.0: + version "1.11.0" + resolved "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== + +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz" + integrity sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g== + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.26.0, babel-core@^6.26.3: + version "6.26.3" + resolved "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz" + integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + +babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz" + integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz" + integrity sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q== + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz" + integrity sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ== + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz" + integrity sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA== + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz" + integrity sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ== + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz" + integrity sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q== + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz" + integrity sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz" + integrity sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz" + integrity sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz" + integrity sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg== + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz" + integrity sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg== + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz" + integrity sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw== + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz" + integrity sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ== + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-loader@^8.2.2: + version "8.2.5" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.5.tgz#d45f585e654d5a5d90f5350a779d7647c5ed512e" + integrity sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ== + dependencies: + find-cache-dir "^3.3.1" + loader-utils "^2.0.0" + make-dir "^3.1.0" + schema-utils "^2.6.5" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz" + integrity sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz" + integrity sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" + +babel-plugin-external-helpers@^6.22.0: + version "6.22.0" + resolved "https://registry.npmjs.org/babel-plugin-external-helpers/-/babel-plugin-external-helpers-6.22.0.tgz" + integrity sha512-TdAMiM6MzLokhk3yCA0KCctmivVZ/mmCwbp7YPmRGkqh2KkcNuxE3R0jxuYU+4xmvfMZx4p4uo8d1cT9t5BLxA== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-module-resolver@^3.1.1: + version "3.2.0" + resolved "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-3.2.0.tgz" + integrity sha512-tjR0GvSndzPew/Iayf4uICWZqjBwnlMWjSx6brryfQ81F9rxBVqwDJtFCV8oOs0+vJeefK9TmdZtkIFdFe1UnA== + dependencies: + find-babel-config "^1.1.0" + glob "^7.1.2" + pkg-up "^2.0.0" + reselect "^3.0.1" + resolve "^1.4.0" + +babel-plugin-polyfill-corejs2@^0.3.3: + version "0.3.3" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz" + integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q== + dependencies: + "@babel/compat-data" "^7.17.7" + "@babel/helper-define-polyfill-provider" "^0.3.3" + semver "^6.1.1" + +babel-plugin-polyfill-corejs3@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz" + integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.3" + core-js-compat "^3.25.1" + +babel-plugin-polyfill-regenerator@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz" + integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.3" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz" + integrity sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw== + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz" + integrity sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ== + +babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz" + integrity sha512-C4Aq+GaAj83pRQ0EFgTvw5YO6T3Qz2KGrNRwIj9mSoNHVvdZY4KO2uA6HNtNXCw993iSZnckY1aLW8nOi8i4+w== + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz" + integrity sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ== + +babel-plugin-transform-async-to-generator@^6.22.0: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz" + integrity sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw== + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz" + integrity sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz" + integrity sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.23.0: + version "6.26.0" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz" + integrity sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw== + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.23.0: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz" + integrity sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag== + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz" + integrity sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw== + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.23.0: + version "6.23.0" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz" + integrity sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.22.0: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz" + integrity sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.23.0: + version "6.23.0" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz" + integrity sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.22.0: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz" + integrity sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg== + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz" + integrity sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz" + integrity sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA== + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + 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== + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.23.0: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz" + integrity sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg== + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.23.0: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz" + integrity sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw== + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.22.0: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz" + integrity sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA== + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.23.0: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz" + integrity sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ== + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz" + integrity sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz" + integrity sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz" + integrity sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ== + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz" + integrity sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.23.0: + version "6.23.0" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz" + integrity sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz" + integrity sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ== + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.22.0: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz" + integrity sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ== + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-object-rest-spread@^6.26.0: + version "6.26.0" + resolved "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz" + integrity sha512-ocgA9VJvyxwt+qJB0ncxV8kb/CjfTcECUY4tQ5VT7nP6Aohzobm8CDFaQ5FHdvZQzLmf0sgDxB8iRXZXxwZcyA== + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.26.0" + +babel-plugin-transform-regenerator@^6.22.0: + version "6.26.0" + resolved "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz" + integrity sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg== + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz" + integrity sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-polyfill@^6.26.0: + version "6.26.0" + resolved "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz" + integrity sha512-F2rZGQnAdaHWQ8YAoeRbukc7HS9QgdgeyJ0rQDd485v9opwuPvjpPFcOOT/WmkKTdgy9ESgSPXDcTNpzrGr6iQ== + dependencies: + babel-runtime "^6.26.0" + core-js "^2.5.0" + regenerator-runtime "^0.10.5" + +babel-preset-env@^1.7.0: + version "1.7.0" + resolved "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz" + integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg== + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^3.2.6" + invariant "^2.2.2" + semver "^5.3.0" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz" + integrity sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A== + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz" + integrity sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g== + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz" + integrity sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg== + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz" + integrity sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA== + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz" + integrity sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g== + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz" + integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +block-stream@*: + version "0.0.9" + resolved "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz" + integrity sha512-OorbnJVPII4DuUKbjARAe8u8EfqOmkEEaSFIyoQ7OjTHn6kafxWl0wLgoZ2rXaYd7MyLcDaU4TmhfxtwgcccMQ== + dependencies: + inherits "~2.0.0" + +body-parser@1.20.0: + version "1.20.0" + resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz" + integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.10.3" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +bonjour-service@^1.0.11: + version "1.0.14" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.14.tgz#c346f5bc84e87802d08f8d5a60b93f758e514ee7" + integrity sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ== + dependencies: + array-flatten "^2.1.2" + dns-equal "^1.0.0" + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.5" + +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^3.2.6: + version "3.2.8" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz" + integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== + dependencies: + caniuse-lite "^1.0.30000844" + electron-to-chromium "^1.3.47" + +browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.20.3, browserslist@^4.21.3, browserslist@^4.21.4: + version "4.21.4" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz" + integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== + dependencies: + caniuse-lite "^1.0.30001400" + electron-to-chromium "^1.4.251" + node-releases "^2.0.6" + update-browserslist-db "^1.0.9" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz" + integrity sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g== + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz" + integrity sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A== + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz" + integrity sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ== + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@5.3.1, camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz" + integrity sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw== + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz" + integrity sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg== + +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001400: + version "1.0.30001414" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001414.tgz" + integrity sha512-t55jfSaWjCdocnFdKQoO+d2ct9C59UZg4dY3OnUlSZ447r8pUtIKdp0hpAzrGFultmTC+Us+KpKi4GZl/LXlFg== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" + integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== + +chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz" + integrity sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A== + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.2, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz" + integrity sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg== + +chart.js@^2.9.3: + version "2.9.4" + resolved "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz" + integrity sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A== + dependencies: + chartjs-color "^2.1.0" + moment "^2.10.2" + +chartjs-color-string@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz" + integrity sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A== + dependencies: + color-name "^1.0.0" + +chartjs-color@^2.1.0: + version "2.4.1" + resolved "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz" + integrity sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w== + dependencies: + chartjs-color-string "^0.6.0" + color-convert "^1.9.3" + +chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz" + integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== + +clean-webpack-plugin@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz#a99d8ec34c1c628a4541567aa7b457446460c62b" + integrity sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A== + dependencies: + "@types/webpack" "^4.4.31" + del "^4.1.1" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz" + integrity sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw== + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.1" + resolved "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz" + integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz" + integrity sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz" + integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== + +color-convert@^1.9.0, color-convert@^1.9.3: + version "1.9.3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colord@^2.9.1: + version "2.9.3" + resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" + integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== + +colorette@^2.0.10, colorette@^2.0.14: + version "2.0.19" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" + integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^7.0.0, commander@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + +compose-function@3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz" + integrity sha512-xzhzTJ5eC+gmIzvZq+C3kCJHsp9os6tJkrigDRZclyGtOKINbZtE8n1Tzmeh32jW+BUDPbvZpibwvJHBLGMVwg== + dependencies: + arity-n "^1.0.4" + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +concat-stream@^1.6.0: + version "1.6.2" + resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +connect-history-api-fallback@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" + integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== + +consola@^2.6.0: + version "2.15.3" + resolved "https://registry.yarnpkg.com/consola/-/consola-2.15.3.tgz#2e11f98d6a4be71ff72e0bdf07bd23e12cb61550" + integrity sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw== + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@1.7.0: + version "1.7.0" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + +convert-source-map@^0.3.3: + version "0.3.5" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz" + integrity sha512-+4nRk0k3oEpwUB7/CalD7xE2z4VmtEnnq0GO2IPTkrooTrAhEsWvuLF5iWP1dXrwluki/azwXV1ve7gtYuPldg== + +convert-source-map@^1.5.1, convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +core-js-compat@^3.25.1: + version "3.25.3" + resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.3.tgz" + integrity sha512-xVtYpJQ5grszDHEUU9O7XbjjcZ0ccX3LgQsyqSvTnjX97ZqEgn9F5srmrwwwMtbKzDllyFPL+O+2OFMl1lU4TQ== + dependencies: + browserslist "^4.21.4" + +core-js@^2.4.0, core-js@^2.5.0: + version "2.6.12" + resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz" + integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cross-spawn@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz" + integrity sha512-eZ+m1WNhSZutOa/uRblAc9Ut5MQfukFrFMtPSm3bZCA888NmMd5AWXWdgRZ80zd+pTk1P2JrGjg9pUPTvl2PWQ== + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cross-spawn@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz" + integrity sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A== + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-declaration-sorter@^6.3.0: + version "6.3.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz#be5e1d71b7a992433fb1c542c7a1b835e45682ec" + integrity sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w== + +css-loader@^5.2.4: + version "5.2.7" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.7.tgz#9b9f111edf6fb2be5dc62525644cbc9c232064ae" + integrity sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg== + dependencies: + icss-utils "^5.1.0" + loader-utils "^2.0.0" + postcss "^8.2.15" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.1.0" + schema-utils "^3.0.0" + semver "^7.3.5" + +css-minimizer-webpack-plugin@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-2.0.0.tgz#3c42f6624ed4cf4780dd963e23ee649e5a25c1a8" + integrity sha512-cG/uc94727tx5pBNtb1Sd7gvUPzwmcQi1lkpfqTpdkuNq75hJCw7bIVsCNijLm4dhDcr1atvuysl2rZqOG8Txw== + dependencies: + cssnano "^5.0.0" + jest-worker "^26.3.0" + p-limit "^3.0.2" + postcss "^8.2.9" + schema-utils "^3.0.0" + serialize-javascript "^5.0.1" + source-map "^0.6.1" + +css-select@^4.1.3: + version "4.3.0" + resolved "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz" + integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== + dependencies: + boolbase "^1.0.0" + css-what "^6.0.1" + domhandler "^4.3.1" + domutils "^2.8.0" + nth-check "^2.0.1" + +css-tree@^1.1.2, css-tree@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== + dependencies: + mdn-data "2.0.14" + source-map "^0.6.1" + +css-what@^6.0.1: + version "6.1.0" + resolved "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + +css@^2.0.0: + version "2.2.4" + resolved "https://registry.npmjs.org/css/-/css-2.2.4.tgz" + integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw== + dependencies: + inherits "^2.0.3" + source-map "^0.6.1" + source-map-resolve "^0.5.2" + urix "^0.1.0" + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +cssnano-preset-default@^5.2.12: + version "5.2.12" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.12.tgz#ebe6596ec7030e62c3eb2b3c09f533c0644a9a97" + integrity sha512-OyCBTZi+PXgylz9HAA5kHyoYhfGcYdwFmyaJzWnzxuGRtnMw/kR6ilW9XzlzlRAtB6PLT/r+prYgkef7hngFew== + dependencies: + css-declaration-sorter "^6.3.0" + cssnano-utils "^3.1.0" + postcss-calc "^8.2.3" + postcss-colormin "^5.3.0" + postcss-convert-values "^5.1.2" + postcss-discard-comments "^5.1.2" + postcss-discard-duplicates "^5.1.0" + postcss-discard-empty "^5.1.1" + postcss-discard-overridden "^5.1.0" + postcss-merge-longhand "^5.1.6" + postcss-merge-rules "^5.1.2" + postcss-minify-font-values "^5.1.0" + postcss-minify-gradients "^5.1.1" + postcss-minify-params "^5.1.3" + postcss-minify-selectors "^5.2.1" + postcss-normalize-charset "^5.1.0" + postcss-normalize-display-values "^5.1.0" + postcss-normalize-positions "^5.1.1" + postcss-normalize-repeat-style "^5.1.1" + postcss-normalize-string "^5.1.0" + postcss-normalize-timing-functions "^5.1.0" + postcss-normalize-unicode "^5.1.0" + postcss-normalize-url "^5.1.0" + postcss-normalize-whitespace "^5.1.1" + postcss-ordered-values "^5.1.3" + postcss-reduce-initial "^5.1.0" + postcss-reduce-transforms "^5.1.0" + postcss-svgo "^5.1.0" + postcss-unique-selectors "^5.1.1" + +cssnano-utils@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861" + integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== + +cssnano@^5.0.0: + version "5.1.13" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.13.tgz#83d0926e72955332dc4802a7070296e6258efc0a" + integrity sha512-S2SL2ekdEz6w6a2epXn4CmMKU4K3KpcyXLKfAYc9UQQqJRkD/2eLUG0vJ3Db/9OvO5GuAdgXw3pFbR6abqghDQ== + dependencies: + cssnano-preset-default "^5.2.12" + lilconfig "^2.0.3" + yaml "^1.10.2" + +csso@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== + dependencies: + css-tree "^1.1.2" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz" + integrity sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng== + dependencies: + array-find-index "^1.0.1" + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/d/-/d-1.0.1.tgz" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz" + integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== + dependencies: + assert-plus "^1.0.0" + +debug@2.6.9, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.1.0, debug@^3.2.7: + version "3.2.7" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.0, debug@^4.1.1: + version "4.3.4" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz" + integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og== + +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz" + integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== + +deep-is@~0.1.3: + version "0.1.4" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +define-properties@^1.1.3, define-properties@^1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +del@^4.1.1: + version "4.1.1" + resolved "https://registry.npmjs.org/del/-/del-4.1.1.tgz" + integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== + dependencies: + "@types/glob" "^7.1.1" + globby "^6.1.0" + is-path-cwd "^2.0.0" + is-path-in-cwd "^2.0.0" + p-map "^2.0.0" + pify "^4.0.1" + rimraf "^2.6.3" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz" + integrity sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A== + dependencies: + repeating "^2.0.0" + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz" + integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== + +dns-packet@^5.2.2: + version "5.4.0" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.4.0.tgz#1f88477cf9f27e78a213fb6d118ae38e759a879b" + integrity sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g== + dependencies: + "@leichtgewicht/ip-codec" "^2.0.1" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +dom-converter@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" + +dom-serializer@^1.0.1: + version "1.4.1" + resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz" + integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: + version "4.3.1" + resolved "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz" + integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== + dependencies: + domelementtype "^2.2.0" + +domutils@^2.5.2, domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz" + integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.3.47, electron-to-chromium@^1.4.251: + version "1.4.268" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.268.tgz" + integrity sha512-PO90Bv++vEzdln+eA9qLg1IRnh0rKETus6QkTzcFm5P3Wg3EQBZud5dcnzkpYXuIKWBjKe5CO8zjz02cicvn1g== + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz" + integrity sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +enhanced-resolve@^5.10.0: + version "5.10.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" + integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +envinfo@^7.7.3: + version "7.8.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" + integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== + +error-ex@^1.2.0: + version "1.3.2" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +error-stack-parser@^2.0.0: + version "2.1.4" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" + integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== + dependencies: + stackframe "^1.3.4" + +es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5: + version "1.20.3" + resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.3.tgz" + integrity sha512-AyrnaKVpMzljIdwjzrj+LxGmj8ik2LckwXacHqrJJ/jxz6dDDBcZ7I7nlHM0FvEW8MfbWJwOd+yT2XzYW49Frw== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.1.3" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-property-descriptors "^1.0.0" + has-symbols "^1.0.3" + internal-slot "^1.0.3" + is-callable "^1.2.6" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-weakref "^1.0.2" + object-inspect "^1.12.2" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.4.3" + safe-regex-test "^1.0.0" + string.prototype.trimend "^1.0.5" + string.prototype.trimstart "^1.0.5" + unbox-primitive "^1.0.2" + +es-module-lexer@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== + +es-shim-unscopables@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz" + integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== + dependencies: + has "^1.0.3" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.35, es5-ext@^0.10.50: + version "0.10.62" + resolved "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz" + integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + next-tick "^1.1.0" + +es6-iterator@2.0.3, es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.3" + resolved "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-config-airbnb-base@^12.1.0: + version "12.1.0" + resolved "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz" + integrity sha512-/vjm0Px5ZCpmJqnjIzcFb9TKZrKWz0gnuG/7Gfkt0Db1ELJR51xkZth+t14rYdqWgX836XbuxtArbIHlVhbLBA== + dependencies: + eslint-restricted-globals "^0.1.1" + +eslint-import-resolver-babel-module@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/eslint-import-resolver-babel-module/-/eslint-import-resolver-babel-module-4.0.0.tgz" + integrity sha512-aPj0+pG0H3HCaMD9eRDYEzPdMyKrLE2oNhAzTXd2w86ZBe3s7drSrrPwVTfzO1CBp13FGk8S84oRmZHZvSo0mA== + dependencies: + pkg-up "^2.0.0" + resolve "^1.4.0" + +eslint-import-resolver-node@^0.3.6: + version "0.3.6" + resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz" + integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== + dependencies: + debug "^3.2.7" + resolve "^1.20.0" + +eslint-module-utils@^2.7.3: + version "2.7.4" + resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz" + integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== + dependencies: + debug "^3.2.7" + +eslint-plugin-import@^2.11.0: + version "2.26.0" + resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz" + integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== + dependencies: + array-includes "^3.1.4" + array.prototype.flat "^1.2.5" + debug "^2.6.9" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.6" + eslint-module-utils "^2.7.3" + has "^1.0.3" + is-core-module "^2.8.1" + is-glob "^4.0.3" + minimatch "^3.1.2" + object.values "^1.1.5" + resolve "^1.22.0" + tsconfig-paths "^3.14.1" + +eslint-restricted-globals@^0.1.1: + version "0.1.1" + resolved "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz" + integrity sha512-d1cerYC0nOJbObxUe1kR8MZ25RLt7IHzR9d+IOupoMqFU03tYjo7Stjqj04uHx1xx7HKSE9/NjdeBiP4/jUP8Q== + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-scope@^3.7.1: + version "3.7.3" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz" + integrity sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-visitor-keys@^1.0.0: + 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== + +eslint@^4.19.1: + version "4.19.1" + resolved "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz" + integrity sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ== + dependencies: + ajv "^5.3.0" + babel-code-frame "^6.22.0" + chalk "^2.1.0" + concat-stream "^1.6.0" + cross-spawn "^5.1.0" + debug "^3.1.0" + doctrine "^2.1.0" + eslint-scope "^3.7.1" + eslint-visitor-keys "^1.0.0" + espree "^3.5.4" + esquery "^1.0.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.0.1" + ignore "^3.3.3" + imurmurhash "^0.1.4" + inquirer "^3.0.6" + is-resolvable "^1.0.0" + js-yaml "^3.9.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.4" + minimatch "^3.0.2" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + pluralize "^7.0.0" + progress "^2.0.0" + regexpp "^1.0.1" + require-uncached "^1.0.3" + semver "^5.3.0" + strip-ansi "^4.0.0" + strip-json-comments "~2.0.1" + table "4.0.2" + text-table "~0.2.0" + +espree@^3.5.4: + version "3.5.4" + resolved "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz" + integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A== + dependencies: + acorn "^5.5.0" + acorn-jsx "^3.0.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.0.0: + version "1.4.0" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.1.0, esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +express@^4.17.3: + version "4.18.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" + integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.0" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.10.3" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext@^1.1.2: + version "1.7.0" + resolved "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz" + integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== + dependencies: + type "^2.7.2" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^2.0.4: + version "2.2.0" + resolved "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz" + integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" + +extsprintf@1.3.0, extsprintf@^1.2.0: + version "1.3.0" + resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz" + integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== + +fast-async@^6.3.7: + version "6.3.8" + resolved "https://registry.npmjs.org/fast-async/-/fast-async-6.3.8.tgz" + integrity sha512-TjlooyqrYm/gOXjD2UHNwfrWkvTbzU105Nk4bvcRTeRoL+wIeK6rqbqDg3CN9z5p37cE2iXhP6SxQFz8OVIaUg== + dependencies: + nodent-compiler "^3.2.10" + nodent-runtime ">=3.2.1" + +fast-deep-equal@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz" + integrity sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz#37b899ae47e1090e40e3fd2318e4d5f0142ca912" + integrity sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ== + dependencies: + fastest-levenshtein "^1.0.7" + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastest-levenshtein@^1.0.12, fastest-levenshtein@^1.0.7: + version "1.0.16" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" + integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== + +faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz" + integrity sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA== + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz" + integrity sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w== + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +file-loader@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-babel-config@^1.1.0: + version "1.2.0" + resolved "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz" + integrity sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA== + dependencies: + json5 "^0.5.1" + path-exists "^3.0.0" + +find-cache-dir@^3.3.1: + version "3.3.2" + resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz" + integrity sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA== + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz" + integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flat-cache@^1.2.1: + version "1.3.4" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz" + integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg== + dependencies: + circular-json "^0.3.1" + graceful-fs "^4.1.2" + rimraf "~2.6.2" + write "^0.2.1" + +follow-redirects@^1.0.0: + version "1.15.2" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" + integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-monkey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" + integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +fstream@^1.0.0, fstream@^1.0.12: + version "1.0.12" + resolved "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz" + integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +function.prototype.name@^1.1.5: + version "1.1.5" + resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz" + integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + functions-have-names "^1.2.2" + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz" + integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== + +functions-have-names@^1.2.2: + version "1.2.3" + resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz" + integrity sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg== + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +gaze@^1.0.0: + version "1.1.3" + resolved "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz" + integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g== + dependencies: + globule "^1.0.0" + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz" + integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +get-port@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" + integrity sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg== + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz" + integrity sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw== + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz" + integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== + dependencies: + assert-plus "^1.0.0" + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@^7.0.0, glob@^7.0.3, glob@^7.1.2, glob@^7.1.3: + version "7.2.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@~7.1.1: + version "7.1.7" + resolved "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.0.1, globals@^11.1.0: + version "11.12.0" + resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz" + integrity sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw== + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globule@^1.0.0: + version "1.3.4" + resolved "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz" + integrity sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg== + dependencies: + glob "~7.1.1" + lodash "^4.17.21" + minimatch "~3.0.2" + +graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz" + integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz" + integrity sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg== + dependencies: + ansi-regex "^2.0.0" + +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz" + integrity sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz" + integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" + integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== + +htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz" + integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.8" + resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== + +http-proxy-middleware@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz" + integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24, iconv-lite@^0.4.17: + version "0.4.24" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +ignore@^3.3.3: + version "3.3.10" + resolved "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +in-publish@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz" + integrity sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ== + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz" + integrity sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg== + dependencies: + repeating "^2.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + +inquirer@^3.0.6: + version "3.3.0" + resolved "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz" + integrity sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ== + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.4" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + +invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz" + integrity sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ== + +ipaddr.js@1.9.1: + 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== + +ipaddr.js@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" + integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-callable@^1.1.4, is-callable@^1.2.6: + version "1.2.7" + resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-core-module@^2.8.1, is-core-module@^2.9.0: + version "2.10.0" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz" + integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== + dependencies: + has "^1.0.3" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-finite@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz" + integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz" + integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz" + integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-cwd@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + +is-path-in-cwd@^2.0.0: + 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== + dependencies: + is-path-inside "^2.1.0" + +is-path-inside@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz" + integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== + dependencies: + path-is-inside "^1.0.2" + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + +is-plain-object@^2.0.4: + 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== + dependencies: + isobject "^3.0.1" + +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-resolvable@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz" + integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== + +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== + +jest-worker@^26.3.0: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jquery.dirtyforms@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/jquery.dirtyforms/-/jquery.dirtyforms-2.0.0.tgz" + integrity sha512-iGhN+ESRCYgR1Tz3Z5RwKhCZi+1LMQiglHxghtTk10O1KmjvZwd2HUrSsV9Zn3ntFgDzYcQcLNERUAAF4RDT/A== + dependencies: + jquery ">=1.4.2" + +jquery@>=1.4.2, jquery@^3.5.0, jquery@x.*: + version "3.6.1" + resolved "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz" + integrity sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw== + +js-base64@^2.1.8: + version "2.6.4" + resolved "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz" + integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz" + integrity sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg== + +js-yaml@^3.9.1: + version "3.14.1" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz" + integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz" + integrity sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA== + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz" + integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== + +json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz" + integrity sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz" + integrity sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw== + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.2, json5@^2.2.1: + version "2.2.1" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + +jsprim@^1.2.2: + version "1.4.2" + resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz" + integrity sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw== + dependencies: + invert-kv "^1.0.0" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz" + integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lightbox2@^2.9.0: + version "2.11.3" + resolved "https://registry.npmjs.org/lightbox2/-/lightbox2-2.11.3.tgz" + integrity sha512-Q4v6il/OK9ttgEkAxSok/jrI/LUbqTrePFchqP2x/59qaDIZgJjEEc5Xf7peSMc/55Zo5PAgmX6EiN/BeEeUBQ== + +lilconfig@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" + integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz" + integrity sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A== + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + +loader-utils@1.2.3: + version "1.2.3" + resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz" + integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== + dependencies: + big.js "^5.2.2" + emojis-list "^2.0.0" + json5 "^1.0.1" + +loader-utils@^1.0.1: + version "1.4.0" + resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +loader-utils@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz" + integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz" + integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz" + integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== + +lodash@^4.0.0, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.3.0: + version "4.17.21" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz" + integrity sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ== + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lru-cache@^4.0.1: + version "4.1.5" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-dir@^3.0.2, make-dir@^3.1.0: + 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== + dependencies: + semver "^6.0.0" + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz" + integrity sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg== + +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memfs@^3.4.3: + version "3.4.7" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.7.tgz#e5252ad2242a724f938cb937e3c4f7ceb1f70e5a" + integrity sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw== + dependencies: + fs-monkey "^1.0.3" + +meow@^3.7.0: + version "3.7.0" + resolved "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz" + integrity sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA== + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +merge-stream@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz" + integrity sha512-e6RM36aegd4f+r8BZCcYXlO2P3H6xbUM6ktL2Xmf45GAOit9bI4z6/3VU7JwllVO1L7u0UDSg/EhzQ5lmMLolA== + dependencies: + readable-stream "^2.0.1" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^4.0.2: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mini-css-extract-plugin@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.2.tgz#83172b4fd812f8fc4a09d6f6d16f924f53990ca8" + integrity sha512-WhDvO3SjGm40oV5y26GjMJYjd2UMqrLAGKy5YS2/3QKJy2F7jgynuHTir/tgUUOiNQu5saXHdc8reo7YuhhT4Q== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + webpack-sources "^1.1.0" + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@~3.0.2: + version "3.0.8" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz" + integrity sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.6: + version "1.2.6" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: + version "0.5.6" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +moment@^2.10.2: + version "2.29.4" + resolved "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz" + integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns@^7.2.5: + version "7.2.5" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" + integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== + dependencies: + dns-packet "^5.2.2" + thunky "^1.0.2" + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz" + integrity sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ== + +nan@^2.13.2: + version "2.16.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.16.0.tgz#664f43e45460fb98faf00edca0bb0d7b8dce7916" + integrity sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA== + +nanoid@^3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" + integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.5.0, neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + +node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + +node-gyp@^3.8.0: + version "3.8.0" + resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz" + integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3 || 4" + osenv "0" + request "^2.87.0" + rimraf "2" + semver "~5.3.0" + tar "^2.0.0" + which "1" + +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + +node-sass@^4.14: + version "4.14.1" + resolved "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz" + integrity sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g== + dependencies: + async-foreach "^0.1.3" + chalk "^1.1.1" + cross-spawn "^3.0.0" + gaze "^1.0.0" + get-stdin "^4.0.1" + glob "^7.0.3" + in-publish "^2.0.0" + lodash "^4.17.15" + meow "^3.7.0" + mkdirp "^0.5.1" + nan "^2.13.2" + node-gyp "^3.8.0" + npmlog "^4.0.0" + request "^2.88.0" + sass-graph "2.2.5" + stdout-stream "^1.4.0" + "true-case-path" "^1.0.2" + +nodent-compiler@^3.2.10: + version "3.2.13" + resolved "https://registry.npmjs.org/nodent-compiler/-/nodent-compiler-3.2.13.tgz" + integrity sha512-nzzWPXZwSdsWie34om+4dLrT/5l1nT/+ig1v06xuSgMtieJVAnMQFuZihUwREM+M7dFso9YoHfDmweexEXXrrw== + dependencies: + acorn ">= 2.5.2 <= 5.7.5" + acorn-es7-plugin "^1.1.7" + nodent-transform "^3.2.9" + source-map "^0.5.7" + +nodent-runtime@>=3.2.1: + version "3.2.1" + resolved "https://registry.npmjs.org/nodent-runtime/-/nodent-runtime-3.2.1.tgz" + integrity sha512-7Ws63oC+215smeKJQCxzrK21VFVlCFBkwl0MOObt0HOpVQXs3u483sAmtkF33nNqZ5rSOQjB76fgyPBmAUrtCA== + +nodent-transform@^3.2.9: + version "3.2.9" + resolved "https://registry.npmjs.org/nodent-transform/-/nodent-transform-3.2.9.tgz" + integrity sha512-4a5FH4WLi+daH/CGD5o/JWRR8W5tlCkd3nrDSkxbOzscJTyTUITltvOJeQjg3HJ1YgEuNyiPhQbvbtRjkQBByQ== + +"nopt@2 || 3": + version "3.0.6" + resolved "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz" + integrity sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg== + dependencies: + abbrev "1" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.5.0" + resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0: + version "4.1.2" + resolved "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" + integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-inspect@^1.12.2, object-inspect@^1.9.0: + version "1.12.2" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.0, object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.values@^1.1.5: + version "1.1.5" + resolved "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz" + integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz" + integrity sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ== + dependencies: + mimic-fn "^1.0.0" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +open@^8.0.9: + version "8.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" + integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +optionator@^0.8.2: + version "0.8.3" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz" + integrity sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ== + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz" + integrity sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g== + dependencies: + lcid "^1.0.0" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" + integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== + +osenv@0: + version "0.1.5" + resolved "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0, p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz" + integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + 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== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-map@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + +p-retry@^4.5.0: + version "4.6.2" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" + integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== + dependencies: + "@types/retry" "0.12.0" + retry "^0.13.1" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz" + integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz" + integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ== + dependencies: + error-ex "^1.2.0" + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz" + integrity sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ== + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" + integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz" + integrity sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz" + integrity sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg== + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" + integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz" + integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" + integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== + +pkg-dir@^4.1.0, pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz" + integrity sha512-fjAPuiws93rm7mPUu21RdBnkeZNrbfCFCwfAhPWY+rR3zG0ubpe5cEReHOw5fIbfmsxEV/g2kSxGTATY3Bpnwg== + dependencies: + find-up "^2.1.0" + +pkg-up@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" + integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== + dependencies: + find-up "^3.0.0" + +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz" + integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== + +postcss-calc@^8.2.3: + version "8.2.4" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.2.4.tgz#77b9c29bfcbe8a07ff6693dc87050828889739a5" + integrity sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q== + dependencies: + postcss-selector-parser "^6.0.9" + postcss-value-parser "^4.2.0" + +postcss-colormin@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.0.tgz#3cee9e5ca62b2c27e84fce63affc0cfb5901956a" + integrity sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg== + dependencies: + browserslist "^4.16.6" + caniuse-api "^3.0.0" + colord "^2.9.1" + postcss-value-parser "^4.2.0" + +postcss-convert-values@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.2.tgz#31586df4e184c2e8890e8b34a0b9355313f503ab" + integrity sha512-c6Hzc4GAv95B7suy4udszX9Zy4ETyMCgFPUDtWjdFTKH1SE9eFY/jEpHSwTH1QPuwxHpWslhckUQWbNRM4ho5g== + dependencies: + browserslist "^4.20.3" + postcss-value-parser "^4.2.0" + +postcss-discard-comments@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz#8df5e81d2925af2780075840c1526f0660e53696" + integrity sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ== + +postcss-discard-duplicates@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz#9eb4fe8456706a4eebd6d3b7b777d07bad03e848" + integrity sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw== + +postcss-discard-empty@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz#e57762343ff7f503fe53fca553d18d7f0c369c6c" + integrity sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A== + +postcss-discard-overridden@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz#7e8c5b53325747e9d90131bb88635282fb4a276e" + integrity sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw== + +postcss-merge-longhand@^5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.6.tgz#f378a8a7e55766b7b644f48e5d8c789ed7ed51ce" + integrity sha512-6C/UGF/3T5OE2CEbOuX7iNO63dnvqhGZeUnKkDeifebY0XqkkvrctYSZurpNE902LDf2yKwwPFgotnfSoPhQiw== + dependencies: + postcss-value-parser "^4.2.0" + stylehacks "^5.1.0" + +postcss-merge-rules@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.2.tgz#7049a14d4211045412116d79b751def4484473a5" + integrity sha512-zKMUlnw+zYCWoPN6yhPjtcEdlJaMUZ0WyVcxTAmw3lkkN/NDMRkOkiuctQEoWAOvH7twaxUUdvBWl0d4+hifRQ== + dependencies: + browserslist "^4.16.6" + caniuse-api "^3.0.0" + cssnano-utils "^3.1.0" + postcss-selector-parser "^6.0.5" + +postcss-minify-font-values@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz#f1df0014a726083d260d3bd85d7385fb89d1f01b" + integrity sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-minify-gradients@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz#f1fe1b4f498134a5068240c2f25d46fcd236ba2c" + integrity sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw== + dependencies: + colord "^2.9.1" + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + +postcss-minify-params@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.3.tgz#ac41a6465be2db735099bbd1798d85079a6dc1f9" + integrity sha512-bkzpWcjykkqIujNL+EVEPOlLYi/eZ050oImVtHU7b4lFS82jPnsCb44gvC6pxaNt38Els3jWYDHTjHKf0koTgg== + dependencies: + browserslist "^4.16.6" + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + +postcss-minify-selectors@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz#d4e7e6b46147b8117ea9325a915a801d5fe656c6" + integrity sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg== + dependencies: + postcss-selector-parser "^6.0.5" + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-normalize-charset@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed" + integrity sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg== + +postcss-normalize-display-values@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz#72abbae58081960e9edd7200fcf21ab8325c3da8" + integrity sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-positions@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz#ef97279d894087b59325b45c47f1e863daefbb92" + integrity sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-repeat-style@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz#e9eb96805204f4766df66fd09ed2e13545420fb2" + integrity sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-string@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz#411961169e07308c82c1f8c55f3e8a337757e228" + integrity sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-timing-functions@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz#d5614410f8f0b2388e9f240aa6011ba6f52dafbb" + integrity sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-unicode@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz#3d23aede35e160089a285e27bf715de11dc9db75" + integrity sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ== + dependencies: + browserslist "^4.16.6" + postcss-value-parser "^4.2.0" + +postcss-normalize-url@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz#ed9d88ca82e21abef99f743457d3729a042adcdc" + integrity sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew== + dependencies: + normalize-url "^6.0.1" + postcss-value-parser "^4.2.0" + +postcss-normalize-whitespace@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz#08a1a0d1ffa17a7cc6efe1e6c9da969cc4493cfa" + integrity sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-ordered-values@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz#b6fd2bd10f937b23d86bc829c69e7732ce76ea38" + integrity sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ== + dependencies: + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + +postcss-reduce-initial@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz#fc31659ea6e85c492fb2a7b545370c215822c5d6" + integrity sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw== + dependencies: + browserslist "^4.16.6" + caniuse-api "^3.0.0" + +postcss-reduce-transforms@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz#333b70e7758b802f3dd0ddfe98bb1ccfef96b6e9" + integrity sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: + version "6.0.10" + resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz" + integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-svgo@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.1.0.tgz#0a317400ced789f233a28826e77523f15857d80d" + integrity sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA== + dependencies: + postcss-value-parser "^4.2.0" + svgo "^2.7.0" + +postcss-unique-selectors@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz#a9f273d1eacd09e9aa6088f4b0507b18b1b541b6" + integrity sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA== + dependencies: + postcss-selector-parser "^6.0.5" + +postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@7.0.36: + version "7.0.36" + resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz" + integrity sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +postcss@^8.2.15, postcss@^8.2.9: + version "8.4.17" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.17.tgz#f87863ec7cd353f81f7ab2dec5d67d861bbb1be5" + integrity sha512-UNxNOLQydcOFi41yHNMcKRZ39NeXlr8AxGuZJsdub8vIb12fHzcq37DTU/QtbI6WLxNg2gF9Z+8qtRwTj1UI1Q== + dependencies: + nanoid "^3.3.4" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz" + integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== + +pretty-error@^3.0.3: + version "3.0.4" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-3.0.4.tgz#94b1d54f76c1ed95b9c604b9de2194838e5b574e" + integrity sha512-ytLFLfv1So4AO1UkoBF6GXQgJRaKbiSiGFICaOPNwQ3CMvBvXpLRubeQWyPGnsbV/t9ml9qto6IeCsho0aEvwQ== + dependencies: + lodash "^4.17.20" + renderkid "^2.0.6" + +private@^0.1.6, private@^0.1.8: + version "0.1.8" + resolved "https://registry.npmjs.org/private/-/private-0.1.8.tgz" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz" + integrity sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ== + +psl@^1.1.28: + version "1.9.0" + resolved "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@6.10.3: + version "6.10.3" + resolved "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== + dependencies: + side-channel "^1.0.4" + +qs@~6.5.2: + version "6.5.3" + resolved "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz" + integrity sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A== + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz" + integrity sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ== + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.2.2: + version "2.3.7" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6: + version "3.6.0" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" + integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== + dependencies: + resolve "^1.9.0" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz" + integrity sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g== + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +regenerate-unicode-properties@^10.1.0: + version "10.1.0" + resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz" + integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ== + dependencies: + regenerate "^1.4.2" + +regenerate@^1.2.1, regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.10.5: + version "0.10.5" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz" + integrity sha512-02YopEIhAgiBHWeoTiA8aitHDt8z6w+rQqNuIftlM+ZtvSl/brTouaU7DW6GO/cHtvxJvS4Hwv2ibKdxIRi24w== + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz" + integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regenerator-transform@^0.15.0: + version "0.15.0" + resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz" + integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg== + dependencies: + "@babel/runtime" "^7.8.4" + +regex-parser@^2.2.11: + version "2.2.11" + resolved "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz" + integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== + +regexp.prototype.flags@^1.4.3: + version "1.4.3" + resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + functions-have-names "^1.2.2" + +regexpp@^1.0.1: + version "1.1.0" + resolved "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz" + integrity sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw== + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz" + integrity sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ== + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regexpu-core@^5.1.0: + version "5.2.1" + resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.1.tgz" + integrity sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^10.1.0" + regjsgen "^0.7.1" + regjsparser "^0.9.1" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.0.0" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz" + integrity sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g== + +regjsgen@^0.7.1: + version "0.7.1" + resolved "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz" + integrity sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA== + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz" + integrity sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw== + dependencies: + jsesc "~0.5.0" + +regjsparser@^0.9.1: + version "0.9.1" + resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz" + integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== + dependencies: + jsesc "~0.5.0" + +renderkid@^2.0.6: + version "2.0.7" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.7.tgz#464f276a6bdcee606f4a15993f9b29fc74ca8609" + integrity sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ== + dependencies: + css-select "^4.1.3" + dom-converter "^0.2.0" + htmlparser2 "^6.1.0" + lodash "^4.17.21" + strip-ansi "^3.0.1" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz" + integrity sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A== + dependencies: + is-finite "^1.0.0" + +request@^2.87.0, request@^2.88.0: + version "2.88.2" + resolved "https://registry.npmjs.org/request/-/request-2.88.2.tgz" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz" + integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug== + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +require-uncached@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz" + integrity sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w== + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +reselect@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/reselect/-/reselect-3.0.1.tgz" + integrity sha512-b/6tFZCmRhtBMa4xGqiiRp9jh9Aqi2A687Lo265cN0/QohJQEBPiQ52f4QB6i0eF3yp3hmLL21LSGBcML2dlxA== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz" + integrity sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-url-loader@^3.1.2: + version "3.1.4" + resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.4.tgz#3c16caebe0b9faea9c7cc252fa49d2353c412320" + integrity sha512-D3sQ04o0eeQEySLrcz4DsX3saHfsr8/N6tfhblxgZKXxMT2Louargg12oGNfoTRLV09GXhVUe5/qgA5vdgNigg== + dependencies: + adjust-sourcemap-loader "3.0.0" + camelcase "5.3.1" + compose-function "3.0.3" + convert-source-map "1.7.0" + es6-iterator "2.0.3" + loader-utils "1.2.3" + postcss "7.0.36" + rework "1.0.1" + rework-visit "1.0.0" + source-map "0.6.1" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz" + integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== + +resolve@^1.10.0, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.4.0, resolve@^1.9.0: + version "1.22.1" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz" + integrity sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q== + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +rework-visit@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz" + integrity sha512-W6V2fix7nCLUYX1v6eGPrBOZlc03/faqzP4sUxMAJMBMOPYhfV/RyLegTufn5gJKaOITyi+gvf0LXDZ9NzkHnQ== + +rework@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz" + integrity sha512-eEjL8FdkdsxApd0yWVZgBGzfCQiT8yqSc2H1p4jpZpQdtz7ohETiDMoje5PlM8I9WgkqkreVxFUKYOiJdVWDXw== + dependencies: + convert-source-map "^0.3.3" + css "^2.0.0" + +rimraf@2, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rimraf@~2.6.2: + version "2.6.3" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +run-async@^2.2.0: + version "2.4.1" + resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz" + integrity sha512-3xPNZGW93oCjiO7PtKxRK6iOVYBWBvtf9QHDfU23Oc+dLIQmAV//UnyXV/yihv81VS/UqoQPk4NegS8EFi55Hg== + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz" + integrity sha512-Cun9QucwK6MIrp3mry/Y7hqD1oFqTYLQ4pGxaHTjIdaFDWRGGLikqp6u8LcWJnzpoALg9hap+JGk8sFIUuEGNA== + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sass-graph@2.2.5: + version "2.2.5" + resolved "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz" + integrity sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag== + dependencies: + glob "^7.0.0" + lodash "^4.0.0" + scss-tokenizer "^0.2.3" + yargs "^13.3.2" + +sass-loader@^7.0.1: + version "7.3.1" + resolved "https://registry.npmjs.org/sass-loader/-/sass-loader-7.3.1.tgz" + integrity sha512-tuU7+zm0pTCynKYHpdqaPpe+MMTQ76I9TPZ7i4/5dZsigE350shQWe5EZNl5dBidM49TPET75tNqRbcsUZWeNA== + dependencies: + clone-deep "^4.0.1" + loader-utils "^1.0.1" + neo-async "^2.5.0" + pify "^4.0.1" + semver "^6.3.0" + +schema-utils@^2.6.5: + version "2.7.1" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== + dependencies: + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + +schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" + integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.8.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.0.0" + +scss-tokenizer@^0.2.3: + version "0.2.3" + resolved "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz" + integrity sha512-dYE8LhncfBUar6POCxMTm0Ln+erjeczqEvCJib5/7XNkdw1FkUGgwMPY360FY0FgPWQxHWCx29Jl3oejyGLM9Q== + dependencies: + js-base64 "^2.1.8" + source-map "^0.4.2" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz" + integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== + +selfsigned@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61" + integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== + dependencies: + node-forge "^1" + +semantic-ui-css@^2.2.0: + version "2.4.1" + resolved "https://registry.npmjs.org/semantic-ui-css/-/semantic-ui-css-2.4.1.tgz" + integrity sha512-Pkp0p9oWOxlH0kODx7qFpIRYpK1T4WJOO4lNnpNPOoWKCrYsfHqYSKgk5fHfQtnWnsAKy7nLJMW02bgDWWFZFg== + dependencies: + jquery x.* + +"semver@2 || 3 || 4 || 5", semver@^5.3.0: + version "5.7.1" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.3.2, semver@^7.3.5: + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + dependencies: + lru-cache "^6.0.0" + +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz" + integrity sha512-mfmm3/H9+67MCVix1h+IXTpDwL6710LyHuk7+cWC9T1mE0qz4iHhh6r4hU2wrIT9iTsAAC2XQRvfblL028cpLw== + +send@0.18.0: + version "0.18.0" + resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serialize-javascript@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" + integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== + dependencies: + randombytes "^2.1.0" + +serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz" + integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz" + integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== + dependencies: + shebang-regex "^1.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz" + integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz" + integrity sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg== + +slice-ansi@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz" + integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== + dependencies: + is-fullwidth-code-point "^2.0.0" + +slick-carousel@^1.8.1: + version "1.8.1" + resolved "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz" + integrity sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA== + +sockjs@^0.3.24: + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-resolve@^0.5.2: + version "0.5.3" + resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== + dependencies: + source-map "^0.5.6" + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + +source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.4.2: + version "0.4.4" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz" + integrity sha512-Y8nIfcb1s/7DcobUz1yOO1GSp7gyL+D9zLHDehT7iRESqGSxjJ448Sg7rvfgsRJCnKLdSl11uGf0s9X80cH0/A== + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + +source-map@^0.7.3: + version "0.7.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.12" + resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz" + integrity sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +sshpk@^1.7.0: + version "1.17.0" + resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz" + integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + +stackframe@^1.3.4: + version "1.3.4" + resolved "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz" + integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +stdout-stream@^1.4.0: + version "1.4.1" + resolved "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz" + integrity sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA== + dependencies: + readable-stream "^2.0.1" + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" + integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string.prototype.trimend@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz" + integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + +string.prototype.trimstart@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz" + integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + +string_decoder@^1.1.1, string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" + integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz" + integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow== + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz" + integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g== + dependencies: + is-utf8 "^0.2.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz" + integrity sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA== + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + +style-loader@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-2.0.0.tgz#9669602fd4690740eaaec137799a03addbbc393c" + integrity sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +stylehacks@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.0.tgz#a40066490ca0caca04e96c6b02153ddc39913520" + integrity sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q== + dependencies: + browserslist "^4.16.6" + postcss-selector-parser "^6.0.4" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" + integrity sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +svgo@^2.7.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" + integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== + dependencies: + "@trysound/sax" "0.2.0" + commander "^7.2.0" + css-select "^4.1.3" + css-tree "^1.1.3" + csso "^4.2.0" + picocolors "^1.0.0" + stable "^0.1.8" + +sync-rpc@^1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/sync-rpc/-/sync-rpc-1.3.6.tgz#b2e8b2550a12ccbc71df8644810529deb68665a7" + integrity sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw== + dependencies: + get-port "^3.1.0" + +table@4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/table/-/table-4.0.2.tgz" + integrity sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA== + dependencies: + ajv "^5.2.3" + ajv-keywords "^2.1.0" + chalk "^2.1.0" + lodash "^4.17.4" + slice-ansi "1.0.0" + string-width "^2.1.1" + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +tar@^2.0.0: + version "2.2.2" + resolved "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz" + integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== + dependencies: + block-stream "*" + fstream "^1.0.12" + inherits "2" + +terser-webpack-plugin@^5.1.1, terser-webpack-plugin@^5.1.3: + version "5.3.6" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz#5590aec31aa3c6f771ce1b1acca60639eab3195c" + integrity sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ== + dependencies: + "@jridgewell/trace-mapping" "^0.3.14" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + terser "^5.14.1" + +terser@^5.14.1: + version "5.15.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.15.1.tgz#8561af6e0fd6d839669c73b92bdd5777d870ed6c" + integrity sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw== + dependencies: + "@jridgewell/source-map" "^0.3.2" + acorn "^8.5.0" + commander "^2.20.0" + source-map-support "~0.5.20" + +text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz" + integrity sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + 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== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz" + integrity sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw== + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz" + integrity sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw== + +"true-case-path@^1.0.2": + version "1.0.3" + resolved "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz" + integrity sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew== + dependencies: + glob "^7.1.2" + +tsconfig-paths@^3.14.1: + version "3.14.1" + resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz" + integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.1" + minimist "^1.2.6" + strip-bom "^3.0.0" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz" + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz" + integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== + dependencies: + prelude-ls "~1.1.2" + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.npmjs.org/type/-/type-1.2.0.tgz" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.7.2: + version "2.7.2" + resolved "https://registry.npmjs.org/type/-/type-2.7.2.tgz" + integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + +unicode-match-property-value-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz" + integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== + +unicode-property-aliases-ecmascript@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz" + integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +upath@^1.1.0: + version "1.2.0" + resolved "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +update-browserslist-db@^1.0.9: + version "1.0.9" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz" + integrity sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz" + integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +utila@~0.4: + version "0.4.0" + resolved "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz" + integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz" + integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +watchpack@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +webpack-cli@^4.9.1: + version "4.10.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" + integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^1.2.0" + "@webpack-cli/info" "^1.5.0" + "@webpack-cli/serve" "^1.7.0" + colorette "^2.0.14" + commander "^7.0.0" + cross-spawn "^7.0.3" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^2.2.0" + rechoir "^0.7.0" + webpack-merge "^5.7.3" + +webpack-dev-middleware@^5.3.1: + version "5.3.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" + integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== + dependencies: + colorette "^2.0.10" + memfs "^3.4.3" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@^4.0.0: + version "4.11.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz#ae07f0d71ca0438cf88446f09029b92ce81380b5" + integrity sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/serve-static" "^1.13.10" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.5.1" + ansi-html-community "^0.0.8" + bonjour-service "^1.0.11" + chokidar "^3.5.3" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^2.0.0" + default-gateway "^6.0.3" + express "^4.17.3" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.3" + ipaddr.js "^2.0.1" + open "^8.0.9" + p-retry "^4.5.0" + rimraf "^3.0.2" + schema-utils "^4.0.0" + selfsigned "^2.1.1" + serve-index "^1.9.1" + sockjs "^0.3.24" + spdy "^4.0.2" + webpack-dev-middleware "^5.3.1" + ws "^8.4.2" + +webpack-merge@^5.7.3: + version "5.8.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" + integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== + dependencies: + clone-deep "^4.0.1" + wildcard "^2.0.0" + +webpack-sources@^1.1.0: + version "1.4.3" + resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack@^5.35: + version "5.74.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" + integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^0.0.51" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.7.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.10.0" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.4.0" + webpack-sources "^3.2.3" + +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz" + integrity sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ== + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz" + integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== + +which@1, which@^1.2.9: + version "1.3.1" + resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.5" + resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + +wildcard@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" + integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz" + integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrap-ansi@^5.1.0: + 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== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/write/-/write-0.2.1.tgz" + integrity sha512-CJ17OoULEKXpA5pef3qLj5AxTJ6mSt7g84he2WIskKwqFO4T97d5V7Tadl0DYDk7qyUOQD5WlUlOMChaYrhxeA== + dependencies: + mkdirp "^0.5.1" + +ws@^8.4.2: + version "8.9.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.9.0.tgz#2a994bb67144be1b53fe2d23c53c028adeb7f45e" + integrity sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg== + +y18n@^3.2.1: + version "3.2.2" + resolved "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz" + integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== + +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz" + integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^20.2.4: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-parser@^4.2.0: + version "4.2.1" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz" + integrity sha512-+QQWqC2xeL0N5/TE+TY6OGEqyNRM+g2/r712PDNYgiCdXYCApXf1vzfmDSLBxfGRwV+moTq/V8FnMI24JCm2Yg== + dependencies: + camelcase "^3.0.0" + +yargs@^13.3.2: + version "13.3.2" + resolved "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== + dependencies: + 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@^6.4.0: + version "6.6.0" + resolved "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz" + integrity sha512-6/QWTdisjnu5UHUzQGst+UOEuEVwIzFVGBjq3jMTFNs5WJQsH/X6nMURSaScIdF5txylr1Ao9bvbWiKi2yXbwA== + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^4.2.0" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==